I am using EF. This is my LINQ query
public List<Tuple<int, string>> GetList()
{
return (from c in DALContext.MST
select new Tuple<int, string>(c.CD, c.NAME)).ToList();
}
When i call GetList() it throws an exception : Only parameterless constructors and initializers are supported in LINQ to Entities
Instead when i rewrite this query:
List<Tuple<int, string>> lst = new List<Tuple<int, string>>();
var query= (from c in DALContext.MST
select new{c.CD, c.NAME});
foreach (var item in query)
{
lst.Add(new Tuple<int,string>(item.CD,item.NAME));
}
return lst;
It just works fine. Whats wrong with my first query???
The other answers are correct about what's going on, but I didn't see anyone mention the best way to make your code work: AsEnumerable()
public List<Tuple<int, string>> GetList()
{
return (from c in DALContext.MST.AsEnumerable()
select Tuple.Create(c.CD, c.NAME)).ToList();
}
The AsEnumerable
method acts as a boundary between the code that should be translated into SQL and executed in the database server, and the code that should be executed in memory after we've gotten a response from the database. Putting it right after the table name tells EF to get all the records from the MST table, and then run the following code that creates tuples from the values that are returned.
I changed your new Tuple<int, string>
into Tuple.Create
mostly because I don't like typing generic type parameters any more than I have to.
LINQ to EF deals with queries a bit differently than LINQ to SQL. In LINQ to EF, you can not put a constructor with parameters in a LINQ expression, like you did here in the first bit of code:
from c in DALContext.MST
select new Tuple<int, string>(c.CD, c.NAME)
The constructor of Tuple is taking two parameters, and that is not allowed in LINQ to EF.
The reason is explained here:
In part this is a matter of wanting LINQ to Entities to be more explicit about the boundary between what parts of your query execute on the server and what part execute on the client.
With LINQ to SQL, for instance, it is possible to write a LINQ query which not only involves data from the server and functions on the server but also functions that can only be executed on the client and to mix them in together. The LINQ to SQL provider will then do its best to untangle things and execute the parts that it can on the server and other parts on the client. This is nice because it is easy to just write whatever query you want and if at all possible it will work. On the other hand, it's not so nice if you accidentally write a query where the only part which can execute on the server is the most basic thing that returns all the data in one or more tables and then have all the filtering happen on the client (with very nasty perf consequences).
With LINQ to Entities, the boundaries are more explicit. When you write a LINQ query against a LINQ to Entities IQueryable implementation, the entire query executes on the server, and if some part of the query cannot be executed on the server, then an explicit boundary must be created with something like ToQueryable() or ToList(). Once that query is executed and the data retrieved, then you can use LINQ to Objects to further refine the query if you so choose. This way you explicitly know where your boundaries are, and it's easier to track down performance issues and the like. One of the related limitations is that the select statement in LINQ to Entities can create anonymous types or other types as long as they have a default constructor and settable parameters. This minimizes the chance that the select statement has major side effects.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With