2016-11-12 4 views
2

Я новичок в System.Linq.Dynamic.Core. У меня есть это:System.Linq.Dynamic.Core: Как правильно выбрать выбор?

Допустим, мы имеем:

Packs = new List<Pack> 
{ 
    new Pack() 
    { 
     IdAtSource="Pack1", 
     Equipments= new List<Equipment>() 
     { 
      new Equipment 
      { 
       Id=1, 
       GenericEquipment = new GenericEquipment() 
       { 
        Id=7 
       } 
      } 
     } 
    }, 
    new Pack() 
    { 
     IdAtSource="Pack2", 
     Equipments= new List<Equipment>() 
     { 
      new Equipment 
      { 
       Id=2, 
       GenericEquipment = new GenericEquipment() 
       { 
        Id=1 
       } 
      }, 
      new Equipment 
      { 
       Id=2, 
       GenericEquipment = new GenericEquipment() 
       { 
        Id=2 
       } 
      } 
     } 
    } 
} 

Я хотел бы, чтобы выбрать Packs с Equipments, но в выбранном Equipments мне нужно иметь только один с Id=2 для Generic оборудования. (результат должен содержать список пакетов со списком оборудования).

Я попытался это:

querable.Where("Packs.Equipments.Select((GenericEquipment.Id)=1)"); 

, но я чувствую, что я waaay мишени здесь. Также есть страница документации о том, как использовать эту библиотеку?

Большое спасибо

ответ

0

Самая последняя версия 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, у вас есть два варианта:

  1. Добавьте конструктор Pack который принимает соответствующие аргументы
  2. Написать статический метод любого класса, который принимает соответствующие аргументы

Добавьте конструктор 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"); 
+0

Большое вам спасибо за ответ! На самом деле это почти отвечает на мой вопрос. Когда я заканчиваю выбор, мне нужно иметь пакет с * просто * оборудованием, которые имеют GenericEqipments с Id = 1. В списке оборудования должно отображаться только одно оборудование. А также, я не знаю типов во время выполнения, это был просто более простой пример, чтобы дать так. Еще раз спасибо, ваш asnwer очень полезен. – Strawberry

+0

@Strawberry Это то, что происходит в запросе Dynamic LINQ. Сначала мы вызываем '.Select', который создает новый экземпляр' Pack' для каждого начального экземпляра 'Pack', но передает только соответствующее« Equipment »в конструктор нового экземпляра:' Equipments.Where (GenericEquipment) .id = 1) '; то мы вызываем '.Where', чтобы включать только экземпляры' Pack', которые имеют что-то в свойстве 'Equipments'. –

+0

Понял дорогой сэр. Но, к сожалению, это не вариант изменения конструктора, поэтому я могу использовать это решение. – Strawberry

0

Они должны работать:

var equipments= from pack in Packs where pack.Equipments.Any() select pack.Equipments; 

var secondEquipments = from pac in equipments where  
pac.GenericEquipment.Id == 2 select pac; 
//I could use one variable instead of 2 but that would look a little bit complex 

Ссылка MSDN (К сожалению, я на мобильный, так что я не могу переименовать его): https://msdn.microsoft.com/en-us/library/bb397927.aspx

+0

Спасибо добрый сэр! Тем не менее это не отвечает на мой вопрос, как использовать библиотеку Linq.Dynamic.Core. – Strawberry

+0

Нет проблем, но я думаю, что это отвечает на ваш вопрос. Позвольте мне исправить это, пожалуйста :) –

Смежные вопросы