Я работаю над большим приложением, которое использует Динамическую библиотеку LINQ для фильтрации.
Все классы в моем уровне доступа к данным являются производными от общего предка DALAncestor, который, помимо прочего, определяет метод GetData: public abstract List GetData (Filter filter)
Реализация этого метода для клиента будет выглядеть (упрощенно):
public override List<Entities.Customer> GetData(Filter filter) {
var customers = from c in db.Customers
select new Entites.Customer {
ID = c.ID,
FullName = c.Name,
Country = c.Country
};
return = filter.Apply(customers).ToList();
}
«Применить» - это метод, который принимает набор условий и применяет все из них с помощью Dynamic LINQ Libary.
Метод GetData вызывается так:
private void DemoCallGetDataMethod() {
var filter = new Filter();
filter.AddCondition("Country", "Austria");
var list = myCustomerDAL.GetData(filter);
// do something
}
SQL Server получает выбранную оценку:
SELECT [t0].ID, [t0].Name, [t0].Country
FROM Customer [t0]
WHERE [t0].Country = @p0
(@ p0 - параметр со значением, установленным в «Австрия»).
Все отлично работает, если я хочу фильтровать значения только на «верхнем» (главном) уровне. Однако, поскольку я строю свой фильтр на основе ввода пользователя в форме фильтра, в некоторых случаях пользователи хотят фильтровать по значению на уровне детализации (т.е. столбцы для фильтрации известны только после того, как пользователь нажал «Поиск»).
Я не могу найти решение для этого: «Получить всех клиентов из Австрии, которые купили Pepsi».
Я пробовал несколько вещей, но ни одна из них не работает. Основная идея:
1. Добавление поддержки CONTAINS в DynamicLibrary
2. Измените мой код на
public override List<Entities.Customer> GetData(Filter filter) {
var customers = from c in db.Customers
select new Entites.Customer {
ID = c.ID,
FullName = c.Name,
Country = c.Country,
Items = c.Order.SelectMany(o => o.Item).Select(i => i.ItemId).ToList()
};
return = filter.Apply(customers).ToList();
}
private void DemoCallGetDataMethod() {
var filter = new Filter();
filter.AddCondition("Country","=", "Austria");
filter.AddCondition("Items","Contains", "11"); // 11 = Id for Pepsi
var list = myCustomerDAL.GetData(filter);
// do something
}
Исключение составляет:
System.InvalidOperationException: универсальный метод «Contains» для типа «System.Linq.Enumerable» не совместим с предоставленными аргументами и аргументами типа. Аргументы типа не должны предоставляться, если метод не является универсальным.
Кто-нибудь знает, что я делаю не так? Или я просто иду в неправильном направлении, и я должен попробовать другой подход? Который? :)
РЕДАКТИРОВАНИЕ: изменил мой пример