简体   繁体   中英

LINQ to Entities Question - All objects where all items in subcollection appear in another collection?

Hopefully I can explain this to where it make sense, but I'm trying to get a list of objects out of a master list using a speicific and complex (complex to me, at least) set of criteria.

I have a Class called TableInfo that exposes a List of ForeignKeyInfo. ForeignKeyInfo has a string property (among others) called, Table. I need to do some sequential processing using my TableInfo objects but only work with the TableInfo objects I haven't yet processed. To keep track of which TableInfo objects have already been processed I have a List which stores the name of the table after the processing has been complete.

I want to loop until all of the items in my TableInfo collection appear in my processed list. For each iteration of the loop, I should be processing all of the TableInfo items where all of the ForeignKeyInfo.Table strings appear in my processed List.

Here's how I've written it in "standard" looping code:

while(processed.Count != _tables.Count)
{
     List<TableInfo> thisIteration = new List<TableInfo>();

     foreach (TableInfo tab in _tables)
     {
          bool allFound = true;
          foreach (ForeignKeyInfo fk in tab.ForeignKeys)
          {
               allFound = allFound && processed.Contains(fk.Table);
          }

          if (allFound && !processed.Contains(tab.Name))
          {
               thisIteration.Add(tab);
          }
     }

     //now do processing using thisIteration list
     //variable, "thisIteration", is what I'd like to replace with the result from LINQ
}

This should do it:

var thisIteration = _tables.Where(t => !processed.Contains(t.Name)
                                    && t.ForeignKeys
                                        .All(fk => processed.Contains(fk.Table));

I'm assuming you just need to iterate over the thisIteration collection, in which case leaving it as an IEnumerable is fine. If you need it to be a list, you can just put in a .ToList() call at the end.

I'm not really sure what you're trying to do here. However, you can convert the body of your loop into the following LINQ query, if that makes things simpler...

List<TableInfo> thisIteration = (from tab in _tables
                                 let allFound = tab.ForeignKeys.Aggregate(true, (current, fk) => current && processed.Contains(fk.Table))
                                 where allFound && !processed.Contains(tab.Name)
                                 select tab).ToList();

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