Линк с длинным пунктом - PullRequest
3 голосов
/ 25 мая 2010

Есть ли лучший способ сделать это? Я попытался перебрать коллекцию partsToChange и создать предложение where, но оно объединяет их вместе вместо ORing. Я также не хочу явно делать равенство для каждого элемента в списке partsToChange.

var partsToChange = new Dictionary<string, string> {
    {"0039", "Vendor A"},
    {"0051", "Vendor B"},
    {"0061", "Vendor C"},
    {"0080", "Vendor D"},
    {"0081", "Vendor D"},        
    {"0086", "Vendor D"},
    {"0089", "Vendor E"},
    {"0091", "Vendor F"},
    {"0163", "Vendor E"},
    {"0426", "Vendor B"},
    {"1197", "Vendor B"}
};

var items = new List<MaterialVendor>();
foreach (var x in partsToChange)
{
    var newItems = (
    from m in MaterialVendor 
    where 
        m.Material.PartNumber == x.Key 
        && m.Manufacturer.Name.Contains(x.Value)
    select m
    ).ToList();
    items.AddRange(newItems);
}

Дополнительная информация: я работаю в LINQPad, и это запрос LinqToSql. Здесь MaterialVendor является и классом, и таблицей DataContext.

Редактировать: детали LinqToSql.

Кажется, это лучший метод, который я нашел как для удобочитаемости, так и для уменьшения сложности. Это также имеет дополнительное преимущество, заключающееся в том, что тип коллекции не определен явно. Это означает, что я могу изменить то, что возвращается с анонимным типом.

var predicate = PredicateBuilder.False<MaterialVendor>();

foreach (var x in partsToChange)
{
    var item = x;
    predicate = predicate.Or (m =>
        m.Material.PartNumber == item.Key 
        && m.Manufacturer.Name.Contains(item.Value));
}

var items = from m in MaterialVendor.Where(predicate)
    select m;

Ответы [ 3 ]

8 голосов
/ 25 мая 2010

[Редактировать] Еще лучше, так как partsToChange это Dictionary:

var items = MaterialVendor.Where(m =>
                m.Manufacturer.Name.Contains(partsToChange[m.Material.PartNumber])
            ).ToList();
2 голосов
/ 25 мая 2010

Просмотр PredicateBuilder

Это позволит вам построить выражение Linq to sql в цикле, добавив при необходимости предложения с AND / OR, а затем выполнить его один раз в конце.

0 голосов
/ 25 мая 2010

Размер , где не имеет значения. Запросы внутри цикла - это та часть, которая снижает удобство обслуживания и производительность.

List<MaterialVendor> items = 
(
  from z in MaterialVendor
  let partKey = z.Material.PartNumber
  where partsToChange.ContainsKey(partKey)
  let partValue = partsToChange[partKey]
  where z.Manufacturer.Name.Contains(partValue)
  select z
).ToList();

Теперь, когда мы знаем, что используется linq to sql ... вот запрос смешанного режима.

List<string> keys = partsToChange.Keys.ToList();

List<MaterialVendor> items =  
( 
  from z in MaterialVendor 
  let partKey = z.Material.PartNumber 
  where keys.Contains(partKey)
  select new {MatVendor = z, Name = z.Manufacturer.Name, Key = partKey}
).AsEnumerable()
.Where(x => x.Name.Contains(partsToChange[x.partKey]))
.Select(x => x.MatVendor)
.ToList(); 
...