2015-05-28 2 views
0

У меня есть объект waferMap, содержащий список bluetapes; каждый bluetape содержит список отпечатков, а каждый штамп имеет имя. Мне нужно, чтобы вытащить штамп, основанный на его имени из списка bluetape, и если он не существует, мне нужно, чтобы он возвращал значение null, а не сбой приложения.Нужна помощь в создании элегантного запроса LINQ

Подводя итог по иерархии:

WaferMap has a List<BlueTape> 
BlueTape has a List<DiePrint> 
DiePrint has name (of type string) 

Вот то, что я до сих пор:

print = waferMap.BluetapeList 
        .Select(x => x.DiePrintList) 
        .First(x => x.Contains(print, new DiePrint.Comparer())) 
        .First(x => x.Name == print.Name); 

А вот объект Comparer из класса DiePrint:

public class Comparer : IEqualityComparer<DiePrint> 
    { 
     public bool Equals(DiePrint x, DiePrint y) { return x.Name == y.Name; } 
     public int GetHashCode(DiePrint obj) { return obj.Name.GetHashCode(); } 
    } 

Прямо сейчас он всегда находит совпадение по какой-то причине, даже если ни один штамп в любом из списков печати отсутствует соответствующее имя.

ответ

6
waferMap.BluetapeList 
     .SelectMany(bt => bt.DiePrintList) 
     .FirstOrDefault(dp => dp.Name == print.Name); 

SelectMany flattens lists (docs).

+0

По-прежнему кажется, что найти матч каждый раз. Если print.Name = "-1x8" (который никогда не будет существовать), он все равно вытаскивает что-то. Если я наложу на него идентификатор объекта, он всегда возвращает тот же объект. Иногда я даже получаю два результата, которых никогда не бывает, поскольку каждое имя DiePrint.Name уникально. – kformeck

0

Ваше решение может быть таким же простым, как проверка нулей в вашем методе вашего компаратора.

public bool Equals(DiePrint x, DiePrint y) 
{ 
    if (x == null && y == null) 
    { 
     return true; 
    } 
    else if (x == null || y == null) 
    { 
     return false; 
    } 
    else 
    { 
     return x.Name == y.Name; 
    } 
} 

Это первое место, где «когда что-то нуль он выходит из строя программы» выскакивает на меня. Если это все еще не работает, нам понадобятся дополнительные сведения.

0

Просто используйте SelectMany, чтобы сгладить каждую коллекцию, отфильтровать по вашему желанию и использовать FirstOrDefault, чтобы получить первый элемент, но по умолчанию, если нет, чтобы вернуть значение по умолчанию этого типа (в данном случае - null) ,

var query = from wafer in wafers 
    from tape in wafer.Tapes 
    from die in tape 
    where die.Name == print.Name 
    select tape; 

var firstTape = query.FirstOrDefault(); 
Смежные вопросы