Общая функция с различными параметрами объекта - PullRequest
0 голосов
/ 17 ноября 2018

Я хочу реализовать фильтрацию на стороне сервера для двух таблиц данных, имеющих разные списки IQueryable

public IQueryable<ClassA> search(IQueryable<ClassA> query,string name,string number)
 {
    if (name!= null )
         query = query.Where( a =>a.name.Contains(name) );
    if (number!= null )
         query = query.Where( a =>a.number.ToString().Contains(numbr) );
    return query;
 }

и

public IQueryable<ClassB> search(IQueryable<ClassB> query,string address, string email)
 {
   if (address!= null )
         query = query.Where( a =>a.name.Contains(address) );
   if (email!= null )
         query = query.Where( a =>a.email.Contains(email) );
   return query;
 }

Поскольку реализация такая же, но ClassA и ClassB имеют разные атрибуты, включающиеразличные проверки для поиска значения.

Как создать одну универсальную функцию, в которой я могу выполнять поиск по обоим этим классам?

Ответы [ 3 ]

0 голосов
/ 17 ноября 2018

Улучшение отклика @wannadreams позволяет искать информацию о свойствах только в том случае, если типом элемента назначения является свойство. Вот полный пример.

        class ClassA
        {
            // Will work
            public string Name { get; set; }
            // Will not work
            public string Name;
        }

        public static async Task Main(string[] args)
        {
            IQueryable<ClassA> query = ...
            search(query, Tuple.Create(nameof(ClassA.Name), "myName"));
        }

        public static IQueryable<T> search<T>(
            IQueryable<T> query,
            params Tuple<string, string>[] parameters)
            where T : class
        {
            foreach(var criteria in parameters) {
                var property = typeof(T).GetProperty(criteria.Item1);
                if (property == null) continue;
                // you also need to verify the property was retrievable from the instance.
                query = query.Where(item => property.GetValue(item) != null)
                    .Where(item => property.GetValue(item).ToString().Contains(criteria.Item2));
            }

            return query;
        }
0 голосов
/ 17 ноября 2018

Например, вы можете сделать оба предложения одного и того же интерфейса IPropertyWalker.Он должен иметь индексатор строк. </p> <pre><code>public string this[string key] { switch(key) { case "Name" return Name; //list all you need for your class } }

А затем передайте имена свойств для сравнения данных.

0 голосов
/ 17 ноября 2018

Возможное решение, используя отражение объекта.Параметр имеет две строки в паре.Первый - это имя свойства, второй - его значение.

 public IQueryable<T> search(IQueryable<T> query, params Tuple<string, string>[] parameters)
 {
   Type type = typeof(T);
   PropertyInfo[] properties = type.GetProperties();
   foreach(var parameter in parameters)
   {
     PropertyInfo pi = properties.Where(a => a.Name == parameter.Item1).FirstOrDefault();
     if (pi != null)
     {
       query = query.Where(a => pi.GetValue(a).ToString().Contains(parameter.Item2));
     }
   }

   return query;
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...