0

I have the following query:

var query = (from e in conn.equipments
             select new 
             {
                  id = e.id,
                  status = GetEquipmentStatusText(e.status)
             }).ToList();

public static string GetEquipmentStatusText(int status) {
   return (status == 1) ? "Active" : "Not Active";
}

This results in the error:LINQ to Entities does not recognize the method

How do I fix it in a way that the "GetEquipmentStatusText" can be centralized into a method where it can be called in other LINQ queries?

firebird
  • 3,461
  • 6
  • 34
  • 45

1 Answers1

3

Just don't use that method call instead inline your condition.

status = e.status == 1 ? "Active" : "Not Active"

LINQ to EF would try to convert your LINQ expression to under laying data source language (probably SQL), and since SQL doesn't have any knowledge of your method it would fail.

You can execute your query without that method and then execute your method on in-memory collection. like:

var query = (from e in conn.equipments
             select new 
             {
                  id = e.id,
                  status = e.status
             }).AsEnumerable(); //as Servy pointed out

var result = (from e in query 
             select new 
             {
               id = e.id, 
               status = GetEquipmentStatusText(e.status)
             }).ToList();
Habib
  • 219,104
  • 29
  • 407
  • 436
  • 2
    To quote the question: "How do I fix it in a way that the "GetEquipmentStatusText" can be centralized into a method where it can be called in other LINQ queries?" – Servy Apr 15 '14 at 15:35
  • 1
    @Servy, OP has to do that on in-memory collection then. It can't be translated to Data source language. – Habib Apr 15 '14 at 15:38
  • Wasn't there some sort of way to define custom functions using the weird internal SQL-like query language EF uses and then bind them to .NET functions so you can call them? – Matti Virkkunen Apr 15 '14 at 15:39
  • 1
    You should not use `ToList` to simply define an operation that should take place using linq to objects. You should use `AsEnumearble`. This allows deferred execution to be maintained, it allows the results to be streamed, it can prevent the entire result set from needing to be materialized in memory, and it avoids the needless overhead of creating and populating a `List`. – Servy Apr 15 '14 at 15:39
  • 1
    @Habib Sure, that's one approach, that doesn't mean he should inline it though. – Servy Apr 15 '14 at 15:39
  • You can define it as an `Expression>` can't you? – Rawling Apr 15 '14 at 15:40
  • @Rawling But then how would you use it? he's not selecting out just that string; he's using it as one field within an anonymous type. – Servy Apr 15 '14 at 15:40
  • @Servy Wouldn't `Expression.Invoke` do the trick? I've never tried that though. – MarcinJuraszek Apr 15 '14 at 15:40
  • Oh yeah, you'd have to build it into another expression building the anonymous object. Ick. – Rawling Apr 15 '14 at 15:41
  • @MarcinJuraszek No, most query providers don't support it. – Servy Apr 15 '14 at 15:41
  • @Servy, if that is the only thing that method is doing then I would inline the condition, but I guess there is more going on in the method than just a single line. – Habib Apr 15 '14 at 15:41
  • @MattiVirkkunen - yes, they are called Model Defined Functions: http://stackoverflow.com/questions/5612827/entity-framework-where-do-i-extend-the-csdl-msl – jmoerdyk Apr 15 '14 at 15:42
  • @Habib That or he simply wants to be able to maintain the int->string mapping in one place, so that it can be more effectively maintained. If adding a new status value resulted in code edits all throughout the entire application... – Servy Apr 15 '14 at 15:42