简体   繁体   English

LINQ to SQL 查询中的自定义方法

[英]Custom Method in LINQ to SQL query

是否可以在查询中使用自定义方法,例如:

var result = from u in context.MyTable where MyMethod(u) == 10 select u;

As Pranay explains, you cannot have a custom (C#) method as part of the LINQ to SQL query, because LINQ to SQL wouldn't be able to look at the expression tree of the method and so it cannot translate it to SQL.正如 Pranay 解释的那样,您不能将自定义 (C#) 方法作为 LINQ to SQL 查询的一部分,因为 LINQ to SQL 将无法查看该方法的表达式树,因此它无法将其转换为 SQL。

One option that you have is to write your function in SQL and store it as a SQL function on the SQL Server (possibly, you could also use SQL CLR, but I have not tried that).您拥有的一种选择是用 SQL 编写函数并将其作为 SQL 函数存储在 SQL Server 上(可能,您也可以使用 SQL CLR,但我还没有尝试过)。 Then you can add the function to your DataContext type and LINQ to SQL will translate it to calls to the function on SQL server.然后,您可以将该函数添加到您的DataContext类型,LINQ to SQL 会将其转换为对 SQL 服务器上的函数的调用。 Something like:就像是:

var result = from u in context.MyTable 
             where context.MyMethod(u) == 10 select u; 

The problem, of course, is that you'll need to write the function in SQL (I think SQL CLR could also work - not sure about the performance and other possible complications though)当然,问题是您需要在 SQL 中编写函数(我认为 SQL CLR 也可以工作 - 但不确定性能和其他可能的并发症)

I also wrote an article (some time ago) that shows how to do this when you write the "method" as an expression tree way (as a value of type Expression<Func<...>> ), which is possible, because in this case, the code is compiled as an expression tree.我还写了一篇文章(前段时间),展示了在将“方法”编写为表达式树方式(作为Expression<Func<...>>类型的值)时如何执行此操作,这是可能的,因为在这种情况下,代码被编译为表达式树。 However, there is some postprocessing that has to be done and you can still write just a single expression that can be easily inlined in the LINQ query.但是,有一些后处理必须完成,您仍然可以只编写一个可以轻松内联到 LINQ 查询中的表达式。

Check this full article : What is and what isn't possible with linq查看这篇完整的文章: linq 是什么,什么是不可能的

Following is not possible以下是不可能的

// 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

It compiles with no errors, but when you execute it LINQ to SQL throws an exception saying: "Static method System.Boolean MyTest(LINQTest.Nwind.Product) has no supported translation to SQL."它编译时没有错误,但是当你执行它时,LINQ to SQL 抛出一个异常说:“静态方法 System.Boolean MyTest(LINQTest.Nwind.Product) 不支持到 SQL 的转换。”

The exception is actually thrown when you try to fetch results from q (for example using the foreach statement), because LINQ to SQL attempts to convert the expression trees to T-SQL only when the results are needed and the query must be executed.当您尝试从 q 获取结果(例如使用 foreach 语句)时,实际上会抛出异常,因为 LINQ to SQL 仅在需要结果并且必须执行查询时才尝试将表达式树转换为 T-SQL。

To fix the example you can simply copy the code that checks whether product name starts with "B" to the where clause of the query and it would work fine.要修复该示例,您可以简单地将检查产品名称是否以“B”开头的代码复制到查询的 where 子句中,它会正常工作。

是的,但是如果您使用的是 Linq-to-Sql - 您的方法必须有特殊的代码来处理 SQL 转换。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM