简体   繁体   中英

Need help crafting an elegant LINQ query

I have an object called waferMap that contains list of bluetapes; each bluetape contains a list of die prints and each die print has a name. I need to be able to pull out a die print based off of its name from the bluetape list and if it does not exist, I need it to return null, not crash the application.

To sum up the hierarchy:

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

Here is what I have so far:

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

And here is the comparer object from the DiePrint class:

    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(); }
    }

Right now it always finds a match for some reason, even if no die print in any of the bluetapes die print list exists with the appropriate name.

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

SelectMany flattens lists (docs) .

Your solution might be as easy as checking for nulls in your Equals method of your comparer.

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;
    }
}

That's the first place where "when something's null it crashes the program" jumps out at me. If this still doesn't work, then we'll need more details.

Just use SelectMany to flatten each of the collections, filter on what you need to, and use FirstOrDefault to get the first item but defaulting if there is none to returning the default value of that type (in this case, 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();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM