我一直在玩LINQ-SQL,试图获得可重用的表达式块,我可以热插入其他查询.所以,我从这样的事情开始:
Func<TaskFile, double> TimeSpent = (t =>
t.TimeEntries.Sum(te => (te.DateEnded - te.DateStarted).TotalHours));
Run Code Online (Sandbox Code Playgroud)
然后,我们可以在下面的LINQ查询中使用上面的内容(LINQPad示例):
TaskFiles.Select(t => new {
t.TaskId,
TimeSpent = TimeSpent(t),
})
Run Code Online (Sandbox Code Playgroud)
这会产生预期的输出,除了为插入的表达式生成每行的查询.这在LINQPad中可见.不好.
无论如何,我注意到了这个CompiledQuery.Compile方法.虽然这需要一个DataContext参数,我想我会包括忽略它,并尝试相同Func.所以我最终得到了以下内容:
static Func<UserQuery, TaskFile, double> TimeSpent =
CompiledQuery.Compile<UserQuery, TaskFile, double>(
(UserQuery db, TaskFile t) =>
t.TimeEntries.Sum(te => (te.DateEnded - te.DateStarted).TotalHours));
Run Code Online (Sandbox Code Playgroud)
请注意,我没有使用db参数.但是,现在当我们使用此更新参数时,仅生成1个 SQL查询.Expression已成功转换为SQL并包含在原始查询中.
所以我的最终问题是,是什么让人CompiledQuery.Compile如此特别?似乎DataContext根本不需要该参数,此时我认为它更像是生成完整查询的便利参数.
使用这样的CompiledQuery.Compile方法会被认为是个好主意吗?这似乎是一个大黑客,但它似乎是LINQ重用的唯一可行途径.
UPDATE
使用陈述中的第Func一个Where,我们会看到以下异常,如下所示:
NotSupportedException: Method 'System.Object DynamicInvoke(System.Object[])' has no supported translation to SQL. …Run Code Online (Sandbox Code Playgroud) linq-to-sql ×1