2

I am trying to cut this linq down

 var sys = db.tlkpSystems
 .Where(a => db.tlkpSettings.Where(e => e.Hidden < 3)
 .Select(o => o.System)
 .ToList().Contains(a.System))      //cannot get this part in?
 .OrderBy(a => a.SystemName).ToList();

foreach (var item in sys)
    model.Add(new SettingSystem { 
        System = item.System, 
        SystemName = item.SystemName 
});

I have tried the following:

   List<SettingSystem> model = new List<SettingSystem>();
   model = db.tlkpSettings.Where(e => e.Hidden < 3)
     .OrderBy(e => e.Setting)
     .Select(e => new SettingSystem
     {
      System = e.System,
      SystemName = e.Setting
      }).ToList();

How can I call the .Contains(a.System) part in my query?

Thanks

Harry
  • 3,031
  • 7
  • 42
  • 67

2 Answers2

3

Some general rules when working with LINQ to Entities:

  • Avoid using ToList inside the query. It prevents EF to build a correct SQL query.

  • Don't use Contains when working with entities (tables). Use Any or joins.

Here is your query (in case System is not an entity navigation property):

var sys = db.tlkpSystems
    .Where(a => db.tlkpSettings.Any(e => e.Hidden < 3 && e.System == a.System))
    .OrderBy(a => a.SystemName).ToList();
Ivan Stoev
  • 195,425
  • 15
  • 312
  • 343
  • Seems like the `ToList()` isn't needed since all he does is iterate. – Ed T Mar 23 '16 at 16:44
  • to list is needed as I return a list – Harry Mar 23 '16 at 16:46
  • @EdT Correct, the above is just to present the solution of the problematic part of the OP original query. Instead of `sys` variable and `ToList` \, he can add `.Select(...).ToList()` and get directly the result as in the second query. – Ivan Stoev Mar 23 '16 at 16:52
1

As an addendum, there is also AsEnumerable for when you must pull a query into memory (such as calling methods within another clause). This is generally better than ToList or ToArray since it'll enumerate the query, rather than enumerating, putting together a List/Array, and then enumerating that collection.

David
  • 10,458
  • 1
  • 28
  • 40