5

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?

4

2 回答 2

1

当您声明将通过 LINQ to entity 提供程序执行的 LINQ 查询时,您在 LINQ 中所做的只是构建将传递给底层IQueryable提供程序的表达式树。然后提供程序将您的 LINQ 表达式转换为数据库可以理解的语言 (SQL)。

提供者在哪些表达式可以转换为 SQL 方面受到限制。您的示例无法转换,因为提供程序无法将 Guid 构造函数中的方法调用转换为 SQL。我认为即使您将常量值传递给 Guid 构造函数,您最终也会遇到相同的异常,因此您必须事先创建所需的 Guid。

这是提供者的限制,并且您不能将 LINQ to 实体与 LINQ to 对象混合使用。

于 2013-06-01T12:19:15.500 回答
0

这是一个很好的问题。我很想知道是提供者还是编译器在这里发挥了作用。首先,我将移出request.querystring("param")LINQ 以确保不会干扰。

如果它没有干扰,那么也许查看 IL 以查看编译器 [在第一个工作的实例中] 是否已经调整了代码,以便在将 Guid 语句的值作为文字插入 LINQ 语句之前计算,而不是当涉及匿名类型时,在第二种情况下执行相同的操作...

于 2013-06-01T14:01:30.150 回答