Самая последняя версия Dynamic LINQ представляется проектом here, с документацией here.
Вообще, единственная причина, почему вы должны требовать Dynamic LINQ по сравнению со стандартной LINQ, когда типы являются не известен во время компиляции.
Если вы знаете, во время компиляции, что запрос будет против List<Pack>
, вы можете использовать stanadard LINQ, как показано в следующем коде (обратите внимание, что это изменяет оригинальные экземпляры Pack
):
var usefulPacks = Packs.Select(pack => {
pack.Equipments = pack.Equipments.Where(equipment =>
equipment.GenericEquipment.Id == 1
).ToList();
}).Where(pack => pack.Equipments.Any()).ToList();
Если вам нужны коды, который не изменяет оригинальные экземпляры, этот код создает копию исходных экземпляров:
var usefulPacks = Packs.Select(pack => {
return new Pack() {
IDAtSource = pack.IDAtSource,
Equipments = pack.Equipments.Where(equipment =>
equipment.GenericEquipment.Id == 1
).ToList();
};
}).Where(pack => pack.Equipments.Any()).ToList();
Обратите внимание, что это не с помощью .SelectMany
— .SelectMany
используется для создания единственного перечисляемого из вложенных перечислений; здесь каждый Pack
в конечном списке соответствует Pack
в первоначальном списке.
Dynamic LINQ не поддерживает изменения или инициализации свойств как часть выражения:
позволяет язык Выражение получать (но не заходящего) значение любого достижимого общественного поля, свойство, или индексатор.
поэтому Equipments
свойство не может быть изменено/инициализирован включать только экземпляры Equipment
, которые соответствуют критериям.
Для того, чтобы установить Equipments
, у вас есть два варианта:
- Добавьте конструктор
Pack
который принимает соответствующие аргументы
- Написать статический метод любого класса, который принимает соответствующие аргументы
Добавьте конструктор Pack
Вы можете добавить конструктор Pack
с соответствующими аргументами, которая устанавливает Equipments
:
Pack(int IDAtSource, IEnumerable<Equipment> equipments) {
this.IDAtSource = IDAtSource;
this.Equipments = equipments.ToList();
}
Затем вы можете использовать следующие:
IQueryable qry = Packs.AsQueryable();
qry = qry
.Select("Pack(IDAtSource, Equipments.Where(GenericEquipment.ID=1))")
.Where("Equipments.Any");
Определить статический метод
public static class MyPackMethods {
public static Pack Create(int IDAtSource, IEnumerable<Equipment> equipments) {
return new Pack() {
IDAtSource = IDAtSource,
Equipments = equipments.ToList()
};
}
}
и называют:
IQueryable qry = Packs.AsQueryable();
qry = qry
.Select("MyPackMethods.Create(IDAtSource, Equipments.Where(GenericEquipment.ID=1))")
.Where("Equipments.Any");
Большое вам спасибо за ответ! На самом деле это почти отвечает на мой вопрос. Когда я заканчиваю выбор, мне нужно иметь пакет с * просто * оборудованием, которые имеют GenericEqipments с Id = 1. В списке оборудования должно отображаться только одно оборудование. А также, я не знаю типов во время выполнения, это был просто более простой пример, чтобы дать так. Еще раз спасибо, ваш asnwer очень полезен. – Strawberry
@Strawberry Это то, что происходит в запросе Dynamic LINQ. Сначала мы вызываем '.Select', который создает новый экземпляр' Pack' для каждого начального экземпляра 'Pack', но передает только соответствующее« Equipment »в конструктор нового экземпляра:' Equipments.Where (GenericEquipment) .id = 1) '; то мы вызываем '.Where', чтобы включать только экземпляры' Pack', которые имеют что-то в свойстве 'Equipments'. –
Понял дорогой сэр. Но, к сожалению, это не вариант изменения конструктора, поэтому я могу использовать это решение. – Strawberry