Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linq to entities: new Guid("") for anonymous type creation vs select

Following my previous question (Only parameterless constructors and initializers are supported in LINQ to Entities) I'm still having a question. I just want to understand what is going on and why something works in one case and not another.

When you want to cast a string parameter (for example a querystring parameter) in a Linq to entities query, you have to use new Guid(request.querystring("param")) instead of Guid.parse(request.querystring("param")). Guid.parse will throw an exception because Linq cannot translate this into SQL.

I'm using this technique often in my code and it works.

dim lstResult = DB.MyTable.Where(function(f) f.key = new Guid(request.querystring("param"))).toList()

But, when I'm trying to create an anonymous type using a Linq query, it will throw an exception:

dim lstResult = DB.MyTable.Where(function(f) f.key = new Guid(request.querystring("param"))).Select(function(f) new With { .guid = f.guid, .name = f.name }).toList()

The thrown exception is:

Only parameterless constructors and initializers are supported in LINQ to Entities

What I could (or should) do is declare the Guid parameter beforehand (and that is maybe good practice) and than using it in the query. It will work:

dim myGuid = Guid.parse(request.querystring("param"))
dim lstResult = DB.MyTable.Where(function(f) f.key = myGuid).Select(function(f) new With { .guid = f.guid, .name = f.name }).toList()

So, my question is: why would it work without creating anonymous types and why is the exception raised when trying to create anonymous types? What is the mechanism causing this exception?

like image 634
CyclingFreak Avatar asked Nov 12 '22 06:11

CyclingFreak


1 Answers

When you declare LINQ query that will be executed via LINQ to entities provider, all you are doing in LINQ is constructing expression tree that will be passed to the underlying IQueryable provider. Your LINQ expression is then converted by the provider to the language that database understands (SQL).

Providers are limited in what expressions can be converted to SQL. Your example can't be converted because provider can't convert method call inside Guid constructor to SQL. I think even if you pass a constant value to the Guid constructor you will end up with the same exception, so you have to create the Guid you need beforehand.

It’s the limitation of the provider and the fact that you can’t mix LINQ to entities with LINQ to objects.

like image 87
Jurica Smircic Avatar answered Nov 14 '22 22:11

Jurica Smircic