简单地说,是什么让像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);
}
答案 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 }})。