为什么LINQ不喜欢内联日期计算?

Bob*_*way 4 c# linq

这个涉及DateTime计算的LINQ表达式编译得很好:

var jobsSinceLastRun = _rep.GetJobs(j => j.CompletedDate > DateTime.Now.AddMonths(-1));
Run Code Online (Sandbox Code Playgroud)

但是当你尝试运行它时,会抛出一个错误:

LINQ to Entities无法识别方法'System.DateTime AddMonths(Int32)'方法,并且此方法无法转换为存储表达式.

很容易修复:

DateTime oneMonthAgo = DateTime.Now.AddMonths(-1);
var jobsSinceLastRun = _rep.GetJobs(j => j.CompletedDate > oneMonthAgo);
Run Code Online (Sandbox Code Playgroud)

但这容易让我想知道幕后是什么导致LINQ拒绝内联计算?抽象的哪个部分失败了?

are*_*yla 5

因为有一个从lambda创建的表达式树,包括这个内联计算.IQueryable接口的LINQ方法要求表达式树类型不是委托.所以表达:

j => j.CompletedDate > DateTime.Now.AddMonths(-1)
Run Code Online (Sandbox Code Playgroud)

EF 6的表达式访问者尝试转换DateTime.Now.AddMonths(-1)为SQL,但不支持此方法的转换.例如,在EF Core中,它受支持,因此可以翻译表达式.表达方式:

j => j.CompletedDate > oneMonthAgo
Run Code Online (Sandbox Code Playgroud)

表达式访问者可以转换oneMonthAgo为SQL,因为它是一个变量,该值可以只包含在SQL中.