2010-03-17 107 views
6

为什么不能我这样做:为什么LINQ to Entities不能识别某些方法?

usuariosEntities usersDB = new usuariosEntities();  
foreach (DataGridViewRow user in dgvUsuarios.Rows) 
{ 
    var rowtoupdate = 
     usersDB.usuarios.Where(
     u => u.codigo_usuario == Convert.ToInt32(user.Cells[0].Value) 
     ).First(); 
    rowtoupdate.password = user.Cells[3].Value.ToString(); 
} 
usersDB.SaveChanges(); 

而且必须这样做:

​​

我必须承认这是一个更可读的代码,但为什么不能这样做?

回答

9

关于它的事情是,LINQ查询被转化编译器转换为表达式树。这个表达式树然后被转换成T-SQL并传递给服务器。 LINQ to SQL将某些方法(如String.Contains)映射到T-SQL等价物。

在第一个例子中,LINQ显然没有将Convert.ToInt32映射到任何东西并抛出异常。它在你的第二个例子中工作的原因是因为Convert.ToInt32调用完成外部的查询,所以它不是表达式树的一部分,也不需要转换为T-SQL。

This MSDN page描述了LINQ to SQL如何将各种数据类型,操作符和方法转换为T-SQL。 (虽然文档确实支持Convert.ToInt32,但我不确定此处可能会发生什么。)

对不起刚刚意识到这是ADO.NET实体框架,而不是LINQ to SQL。 This page lists ADO.NET实体框架映射。这有点限制,主要是因为它需要与多个提供商合作。

+1

有没有办法让L2E将这些方法/函数映射到T-SQL函数? +1清除说明 – Luiscencio 2010-03-17 23:15:40

+0

不,但是如果您在SQL中创建用户定义的函数并将其添加到数据上下文中,则可以在查询中使用它们。 – Josh 2010-03-17 23:16:42

+0

因此,如果我使用mysql并将一些存储过程添加到我的数据库,我可以以某种方式调用它? – Luiscencio 2010-03-17 23:17:46

0

因为你的LINQ to Ent。并没有将查询编译成MSIL与所有的元数据,而只是将查询翻译成一些extantion方法,并且受限于languge的lambda解析能力。这意味着,

验证码:
var results = from c in SomeCollection where c.SomeProperty < someValue * 2 select new {c.SomeProperty, c.OtherProperty};

是一样的:

var results = SomeCollection
.Where(c => c.SomeProperty < someValue * 2)
.Select(c => new {c.SomeProperty, c.OtherProperty});

相关问题