Pobieranie danych według wielu warunków

0

Hej,
jak pobierać dane wg wielu ( kilkunastu ) warunków o które woła klient, Chodzi mi o coś takiego, że mamy formularz z polami wg których chcemy pobrać dane jak ponizej. Jak konstruować warunki? Jak to zrobić z EF Core 7
załóżmy taką encję

	public class Person
	{
		public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Phone { get; set; }
        public string Email { get; set; }
        public string? Street { get; set; }
        public string? ZipCode { get; set; }
        public string? Locality { get; set; }
        public Gender? Gender { get; set; }
        public string? Nationality { get; set; }
    }

i teraz przychodzi przykładowy request

        public string? LastName { get; set; }
        public string? Phone { get; set; }
        public string? Email { get; set; }
        public string? Street { get; set; }
        public string? ZipCode { get; set; }
        public string? Locality { get; set; }
        public Gender? Gender { get; set; }
    // z frontu {
        Phone: "345"; // phone like "%345%"
        Locality: "Paris"; // locality like "%paris%"
        Gender: "Male; // gender == "Male"
      }

wiadomo innym razem może przyjść inny zestaw

0

Ja używam Dappera, więc nie pomogę w kwestii filtrów, ale proszę, zmień to Locality na City 😅 Widziałeś gdzieś, na jakimkolwiek anglojęzycznym formularzu pole z nazwą Locality? Ile razy się walnąłeś na froncie i wpisałeś w filtrze City, i nic nie podpowiedziało? 🤔✌️

0

Budować dynamicznie Expressions.
Istotne jest co tam potrzebujesz. Czy tylko enda czy również or i ich łączenie.
Ja robiłem dynamiczne budowanie expressions + refleksja
a z frontu przesyłałem taką struktrurę.

public class Criteria
    {
        /// <summary>
        /// Represnts list of condition computes as the logical OR.
        /// </summary>
        public IEnumerable<Condition> AnyOf { get; set; }
    }

    public class Condition
    {
        /// <summary>
        /// Name of entity field using in comparison
        /// </summary>
        public string Field { get; set; }

        /// <summary>
        /// Value used in comparison.
        /// </summary>
        public object Value { get; set; }

        /// <summary>
        /// Operator used in comparison. <see cref="ConditionOperator"/>
        /// </summary>
        public string Operator { get; set; }

        public object SecondValue { get; set; }
    }

Wyglądało to mniej więcej tak, że miałem fabryke dla każdego Condition w zależności od operatora. Potem łączyłem to w or a następnie w and.

Ale to jest zabawa. Pewnie jest jakaś biblioteka która by to przyśpieszyła.

0

Po chamaku to tak
Pisze z telefonu.

.Where( x=>
(String.isnullorempty(Phone) || x.Phone ==Phone)
&&
(String.isnullorempty(Locality) || x.Locality == Locality)
).tolist();

0
   protected static IQueryable<T> AddFilter<T>(IQueryable<T> query, string propertyName, string searchTerm)
        {
            try
            {
                var propertyInfo = typeof(T).GetProperty(propertyName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
                
                if (propertyInfo == null)
                    return query;

                var param = Expression.Parameter(typeof(T), "e");
                var propExpression = Expression.Property(param, propertyName);

                object value = searchTerm;
                if (propExpression.Type != typeof(string))
                    value = Convert.ChangeType(value, propExpression.Type);

                var filterLambda = Expression.Lambda<Func<T, bool>>(Expression.Equal(propExpression,Expression.Constant(value)),param);

                return query.Where(filterLambda);
            }
            catch
            {

            }
            return query;

        }

ta linijka

var propertyInfo = typeof(T).GetProperty(propertyName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
                
                if (propertyInfo == null)
                    return query;

jest tylko po to, aby sprawdzic czy dana klasa ma dane property

jest to o tyle wygodne, ze mozesz w zasadzie o kazde pole zapytać
co wazniejsze, jest to bezpieczne przed SQL injection - ale nie mam pojecia jak to sie dzieje,
nawet zapytanie o propertke której nie ma w klasie (bez mojej weryfikacji) nie wyrzuci błędu jakims cudem (tylko nie zwroci rezultatu)

a jesli nie chcesz sie bawic w takie reczne rzeczy, to OData (libka ktora przerzuca zapytanie na strronie frontu, tak jak mozesz sie odwolywac nawet do obiekt.obiektPodrzedny...obiektJeszcezBardziejPodrzedny :D

1 użytkowników online, w tym zalogowanych: 0, gości: 1