什么使“SqlMethods”方法有效?

时间:2010-11-18 21:22:10

标签: c# .net linq linq-to-sql

简单地说,是什么让像SqlMethods.DateDiffDay这样的方法有效?

方法签名如下所示:

public static int DateDiffDay(DateTime startDate, DateTime endDate);

所以内部(或通过一些魔法外部)发生的事情使这项工作:

var query = from a in db.TableA
            group a by SqlMethods.DateDiffDay(a.Start, a.End) into g
            select g.Key;

...为什么将它隐藏在我自己的方法中会使它失败(不是我试图以任何理由这样做,只是试图更好地理解它):

var query = from a in db.TableA
            group a by MyOwnDateDiffDay(DateTime startDate, DateTime endDate) into g
            select g.Key;

public static int MyOwnDateDiffDay(DateTime startDate, DateTime endDate)
{
    return SqlMethods.DateDiffDay(startDate, endDate);
}

2 个答案:

答案 0 :(得分:6)

非常简单:在查看表达式树时,解析引擎是硬编码的,用于发现这些方法并在TSQL中以特定方式解释它们。它实际上从未调用方法 - 这就是您MyOwnDateDiffDay失败的原因 - 它没有被编程为发现MyOwnDateDiffDay

您可以使用通常为L2S封装UDF的[Function(...)]代码在您自己的代码中执行 small 度 - 例如,这是一种厚颜无耻的方式来包装NEWID内置SQL-Server功能:

partial class MyDataContext
{
     [Function(Name="NEWID", IsComposable=true)] 
     public Guid Random() 
     { // to prove not used by our C# code... 
         throw new NotImplementedException(); 
     }
}

答案 1 :(得分:2)

使用LINQ表达式group x by y实际上在源上调用(按名称)GroupBy。如果源实现IEnumerable,这将是一个被调用的常用方法,它接受从源类型到某个键值的任意函数:

一些可枚举的类(例如LINQ to SQL类)不仅实现了IEnumerable<T>,还实现了IQueryable<T>。这意味着还可以使用以下方法:

这里,该方法接收可以解析的expression tree。在LINQ to SQL的情况下,检测到SqlMethods.*的存在,而不是执行该函数,它被转换为相应的SQL Server操作并在SQL Server上执行(在您的情况下,它是{{3 }})。