是否可以在查询中使用自定义方法,例如:
var result = from u in context.MyTable where MyMethod(u) == 10 select u;
答案 0 :(得分:7)
正如Pranay所解释的那样,您不能将自定义(C#)方法作为LINQ to SQL查询的一部分,因为LINQ to SQL无法查看方法的表达式树,因此无法将其转换为SQL。
您拥有的一个选项是在SQL中编写函数并将其作为SQL函数存储在SQL Server上(可能,您也可以使用SQL CLR,但我没有尝试过)。然后,您可以将函数添加到DataContext
类型,LINQ to SQL将其转换为对SQL服务器上的函数的调用。类似的东西:
var result = from u in context.MyTable
where context.MyMethod(u) == 10 select u;
问题当然是你需要在SQL中编写函数(我认为SQL CLR也可以工作 - 不确定性能和其他可能的复杂性)
我也是wrote an article(前一段时间),它显示了如何将“方法”作为表达式树方式(作为类型Expression<Func<...>>
的值)编写,这是可能的,因为在这种情况下,代码被编译为表达式树。但是,有一些必须完成的后处理,你仍然可以编写一个可以在LINQ查询中轻松内联的表达式。
答案 1 :(得分:3)
查看完整文章:What is and what isn't possible with linq
以下是不可能的
// function used in filter
static bool MyFunc(Nwind.Product p)
{
return p.ProductName.StartsWith("B");
}
// query that uses MyFunc
var q =
from p in db.Products
where MyPriceFunc(p.UnitPrice) > 30m
select p
它编译时没有错误,但是当你执行它时,LINQ to SQL会抛出一个异常,说:“静态方法System.Boolean MyTest(LINQTest.Nwind.Product)没有支持的SQL转换。”
当您尝试从q获取结果时(例如使用foreach语句),实际上会抛出异常,因为只有在需要结果并且查询必须是的时候,LINQ to SQL才会尝试将表达式树转换为T-SQL执行。
要修复该示例,您只需将检查产品名称是否以“B”开头的代码复制到查询的where子句中,它就可以正常工作。
答案 2 :(得分:-3)
是的,但如果你使用的是Linq-to-Sql,你的方法必须有特殊的代码来处理SQL转换。