9

How can i refactor this LINQ to make this work?

var a =  (from app in mamDB.Apps where app.IsDeleted == false 
                select string.Format("{0}{1}",app.AppName, 
                app.AppsData.IsExperimental? " (exp)": string.Empty))
               .ToArray();}

I now get error:

LINQ to Entities does not recognize the method 'System.String Format(System.String, System.Object, System.Object)' method, and this method cannot be translated into a store expression.

I have uselessly tried:

return (from app in mamDB.Apps where app.IsDeleted == false 
        select new string(app.AppName + (app.AppsData != null && 
        app.AppsData.IsExperimental)? " (exp)": string.Empty)).ToArray();
Vishal Suthar
  • 17,013
  • 3
  • 59
  • 105
Elad Benda
  • 35,076
  • 87
  • 265
  • 471
  • 1
    http://stackoverflow.com/questions/10079990/linq-to-entities-does-not-recognize-the-method-system-string-formatsystem-stri – Thelonias Jan 08 '13 at 13:29

2 Answers2

17

You can do the string.Format back in LINQ-to-Objects:

var a =  (from app in mamDB.Apps where app.IsDeleted == false 
         select new {app.AppName, app.AppsData.IsExperimental})
         .AsEnumerable()
         .Select(row => string.Format("{0}{1}",
            row.AppName, row.IsExperimental ? " (exp)" : "")).ToArray();
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • 1
    Shouldn't you really be calling `ToList` to **be sure** that the query executes first? – James Jan 08 '13 at 13:45
  • 1
    @James no need; the `AsEnumerable()` breaks the `IQueryable<>` composition, which is all that is required. – Marc Gravell Jan 08 '13 at 13:50
  • I may be wrong, but wouldn't IEnumerable cause the *entire* `mamDB.Apps` table to be pulled into memory and then apply the `where` clause? – James Jan 08 '13 at 14:05
  • @James no, it would not; the original query (before the AsEnumerable) includes a row-filter (`where`) and a column-filter (just selecting `AppName` and `IsExperimental`), and can be evalauted as an streaming iterator block (one row at a time), not a list/array – Marc Gravell Jan 08 '13 at 14:11
  • @James which answer (you've linked the question)? and how does it differ? – Marc Gravell Jan 08 '13 at 14:16
  • Actually, that's my bad I misread the docs on `AsEnumerable`! Thanks for the clarification. RE the question, it was a mistake on my end - I thought the queries were similar but they weren't the OP was calling `AsEnumerable` at table level *before* the where. – James Jan 08 '13 at 14:16
  • @James I think the bit you're looking at is where the accepted answer is talking about the **other** example in the question: `from i in Imports.AsEnumerable() where i.IsActive` - in that one the `where` is **after** the `AsEnumerable`, so the `where` happens via LINQ-to-Objects. – Marc Gravell Jan 08 '13 at 14:18
0

Try this

var a =  (from app in mamDB.Apps where app.IsDeleted == false 
            select new {AppName = app.AppName, IsExperimental = app.AppsData.IsExperimental})
          .Select(app => string.Format("{0}{1}",app.AppName, 
            app.IsExperimental? " (exp)": string.Empty))
           .ToArray();}
Dennis
  • 2,615
  • 2
  • 19
  • 20