Полагаю, вы знаете, как извлечь имя свойства с помощью свойства DataPropertyName
столбца, а также как получить значение из свойства Value
ячейки.
В ответе я сосредоточусьо том, как выполнить динамическую фильтрацию List<T>
с именем свойства и значением , как при использовании .Where(x=>x.PropertyName == Value)
.
Длядля этого у вас есть несколько вариантов, которые вы можете выбрать, в том числе:
- Динамическая библиотека Linq
- Динамическое создание
Expression
во время выполнения - Использование
Dictionary
содержит критерии, которые вам необходимы для каждого свойства - Просто используйте if / else
Я поделюсь более подробной информацией о вышеупомянутых решениях, и вы сможете выбрать любое из них.
Примечание: Если ответ слишком длинный, возможно, самый простой и очевидный ответ - 4-й вариант.
Вариант 1 - Динамическая библиотека Linq
В качестве опции вы можете добавить System.Linq.Dynamic
ссылку на ваш проект, затем послеиспользуя пространство имен System.Linq.Dynamic
, вы сможете создавать динамические запросы на IEnumerable<T>
или IQueryable<T>
, передавая критерии как string
, например:
var list = db.Products.ToList();
var result = list.Where("Name = @0", "product1").ToList();
Таким образом, вы можете просто использовать столбецИмя свойства данных и значение столбца в запросе динамически.Чтобы узнать больше о динамическом linq, взгляните на следующие ресурсы:
Пакет NuGet для System.Linq.Dynamic
.Вы можете установить пакет, просто используя эту команду в консоли диспетчера пакетов: Install-Package System.Linq.Dynamic
GitHub репозиторий для System.Linq.Dynamic
Сообщение Скотта Гатри в блоге о Динамический LINQ (Часть 1. Использование библиотеки динамических запросов LINQ)
Вариант 2 - Создание лямбдыВыражение во время выполнения
В качестве другого варианта вы можете создать лямбда-выражение во время выполнения и использовать его с методом Where
.Например, вы можете создать следующий метод:
//Creates x=>x.Something == value
public Expression<Func<T, bool>> EqualCriteria<T>(string propertyName, object value)
{
var property = typeof(T).GetProperty(propertyName);
var x = Expression.Parameter(typeof(T), "x");
var propertyExpression = Expression.Property(x, property.Name);
var valueExpression = Expression.Convert(Expression.Constant(value),
property.PropertyType);
var criteria = Expression.Equal(propertyExpression, valueExpression);
var lambda = Expression.Lambda<Func<T, bool>>(criteria, x);
return lambda;
}
и затем использовать его следующим образом:
var list = db.Products.ToList();
var result = list.Where(EqualCriteria<Product>("Name", "product1").Compile()).ToList();
Как вы можете видеть, также в этом решении вы можете использовать данные столбцаимя и значение свойства динамически.
Вариант 3. Использование предопределенных критериев в словаре
В качестве другого варианта вы можете создать словарь, содержащий необходимые критерии, а затем использовать их динамически.Например, допустим, вы создали следующий словарь:
var criterias = new Dictionary<string, Func<Product, object, bool>>() {
{ "Id" , (p,v)=>p.Id.Equals(v) },
{ "Name" , (p,v)=>p.Name.Equals(v) }
};
Затем, основываясь на имени свойства данных столбца и значении ячейки, вы можете просто использовать следующую инструкцию для фильтрации списка:
var list = db.Products.ToList();
var result = list.Where(x => criterias["Name"](x, "product1")).ToList();
Опция 4 - Использование if / else
В качестве другой опции вы можете просто использовать условия if / else.Например, допустим, у вас есть значение в переменной объекта и имя свойства в строковой переменной, тогда вы можете написать:
var list = db.Products.ToList();
var result = list.ToList();
if (propertyName == "Id")
{
result = result.Where(x=>x.Id == (int)value).ToList();
}
else if (propertyName == "Name")
{
result = result.Where(x=>x.Name == (string)value).ToList();
}