3

LINQ to Entities does not recognize the method...

Guys, I'm sorry. I realize that this issue has been brought up by hundreds of people already. Unfortunately I have been reaching my mental boundaries already and none of the answers I found seemed to match my case.

Here is what I tried to do:

var apiMenuItems = menuItems.Select(item => new ApiMenuItem()
            {
                ID = item.ID,
                Name = item.Name.GetLocalizedString("en")
            });

As you can see I want to create a couple new objects of type ApiMenuItem (which is a very simple class).

 public class ApiMenuItem
 {
    public Guid ID { get; set; }
    public string Name { get; set; }
 }

As far as I understood, Entity Framework needs to convert my LINQ statement to pure SQL. This does not work with my GetLocalizedString(string languageCode) extension method.

Could anybody please help me out with some code that fixes this issue - or works around it? I really can't come up with a solution myself :-(

Thanks so much for your help!

Ingmar
  • 1,525
  • 6
  • 34
  • 51
  • 1
    How is `menuItems` initialized? – jrummell Jan 16 '13 at 15:29
  • 2
    Have you tried the standard solution using `ToList()` before the call to `Select`? – Daniel Hilgarth Jan 16 '13 at 15:29
  • Can you give the definition of the type of `item`? – sinelaw Jan 16 '13 at 15:38
  • 4
    @DanielHilgarth You should use `AsEnumerable` to ensure that a query is evaluated through LINQ to Objects, rather than ToList, so as to not pointlessly materialize the entire list and bring all items into memory as opposed to allowing the items to be streamed. – Servy Jan 16 '13 at 15:42
  • @Servy: Thanks for bringing this up. Marc Gravell just told me something similar earlier today, but I wonder how that actually works. `AsEnumerable` doesn't do anything, it just returns the passed in enumerable. How does that actually switch the "context" from EF to L2O? – Daniel Hilgarth Jan 16 '13 at 15:43
  • 3
    @DanielHilgarth Because it returns an `IEnumerable` and not an `IQueryable`, thus all of the future LINQ methods you use will use the `IEnumerable` overload and not the `IQueryable` overload. – Servy Jan 16 '13 at 15:47
  • Good Morning guys, and thanks so much for your suggestions. In fact, both solutions work: .ToList() and .AsEnumerable(). Of course I prefer the .AsEnumerable() approach due to the reasons Servy mentioned. I can't believe how easy this was to fix. Thank you so much guys. This really caused me a lot of pain! – Ingmar Jan 17 '13 at 05:33
  • I'm still not really familiar with stack overflow.com. Is there anything I can do besides voting up both of your comments? Thanks again! – Ingmar Jan 17 '13 at 05:35

1 Answers1

2

It works if you use ToList() to fetch the items from the database before you select ApiMenuItem:

var apiMenuItems = menuItems.ToList().Select(item => new ApiMenuItem()
{
    ID = item.ID,
    Name = item.Name.GetLocalizedString("en")
});

But for performance reasons you should do it like this:

var apiMenuItems = menuItems.Select(item => new 
{
    //What to select from db
    ID = item.ID, 
    Name = item.Name
}).ToList() //Fetch from db
.Select(item => new ApiMenuItem()
{
    //Select with code
    ID = item.ID,
    Name = item.Name.GetLocalizedString("en")
});
Robert Fricke
  • 3,637
  • 21
  • 34
  • Hi fricke, you are right. This works. But DanielHilgarth already suggested this (please see above). Thanks though for your help! – Ingmar Jan 17 '13 at 11:31