Back from the holiday an nice surprise was awaiting for me: I’ve to “finalize” (as in make it work) an application that someone that left the company developed more than one year ago. Among the other problems one real surprised me: the project is built with .NET 3.5 and uses Entity Framework v1 and in some the queries failed with the following strange error:
Only parameterless constructors and initializers are supported in LINQ to Entities.
Just to be clear, it was a runtime error, not a build failure.
The queries that were failing were all, more or less, like the following one:
var photo = (from p in context.PhotoSet where p.num == new Guid(id) && p.LangId == langId select p).FirstOrDefault();
The code seemed perfect to me: I’m looking for a Photo whose id (a Guid) is like the one provided.
Looking around the web I found a blog post by Muhammad Mosa, “LINQ to Entities, what is not supported?”, which explains that you cannot instantiate new objects through a constructor with parameters (just as the exception says pretty clearly). Also Julie “Ms. EF” Lerman treated this problem in a blog post titled “A few things you can't do with EF queries which you won't find out until runtime”. But all the samples were about custom objects or complex objects like collections being instantiated with values coming from the query, but in my case I was creating a simple .NET core object with a string coming from outside of the query. So I was still not understanding why my query was failing. But it turned out that also creating the Guid inside the LINQ query is not allowed. So the solution for my problem is:
Guid guid = new Guid(id); var photo = (from p in context.PhotoSet where p.num == guid && p.LangId == langId select p).FirstOrDefault();
What I did is just instantiating the Guid outside of the LINQ query and use the variable inside LINQ.
I had this problem with EF1, but given the explanation provided by the team, I guess you will encounter this issue (which is not a bug but is “by design”) in EF4 as well. Which might make sense if you use parameters coming from inside the query, but not if you are creating an object with variables that have nothing to do with LINQ query itself. Can anyone comment on this?
This experience gave me another good reason to continue using NHibernate :)