我有一个奇怪的LINQ问题system.function。如果我的Lambda表达式包含datacontext两次,它将生成多个SQL查询,而不是(请参阅第二个)一个SQL查询。
第一
Dim whereFunction As Func(Of tasks, Boolean) = Function(task) New With {.condition =
(From i In myDataContext.taskInfo Where i.taskId = task.id).Any()
}.condition
Dim tasksLambda = myDataContext.tasks.Where(whereFunction)
Dim taskList = tasksLambda.ToList
'generates for each task one select to taskinfo on SQL Server Profiler -> bad
第二
Dim tasksNoLambda = (From task In myDataContext.tasks Where (From i In myDataContext.taskInfo Where i.taskId = task.id).Any())
taskList = tasksNoLambda .ToList
'generates only one select to tasks with subselect to taskinfo on SQL Server Profiler -> good
你能解释为什么它会进行多个查询而不是子查询和/或这两个Lambda查询之间有什么区别。
提前致谢,
丹尼尔
答案 0 :(得分:2)
myDataContext.tasks
是指数据源提供的集合
.Where(whereFunction)
是一个必须在客户端中进行求值的表达式,因为whereFunction
通常无法转换为SQL表达式(它正在构建新的匿名对象,我相信那里& #39;没有SQL转换)。
myDataContext.taskInfo
再次引用数据源。
因此,在评估最高级别表达式时,需要进行大量的来回通信,从数据源检索数据,在客户端上的函数中处理数据,这反过来又必须从中检索更多数据。数据源。
你可以在没有匿名对象的情况下尝试相同的事情吗?你能试试吗?
Dim whereFunction As Func(Of tasks, Boolean) = _
Function(task) (From i In myDataContext.taskInfo Where i.taskId = task.id).Any())
知道了。第二次尝试 - 试试这个:
Dim whereFunction As System.Linq.Expressions.Expression(Of Func(Of tasks, Boolean)) = _
Function(task) (From i In myDataContext.taskInfo Where i.taskId = task.id).Any())
通过将变量表示为LINQ"表达式"我认为它提高了LINQ将其转换为其他形式(如SQL)的能力。
答案 1 :(得分:1)
尝试这样做:
Dim tasksLambda = _
From task In myDataContext.tasks
Group Join i In myDataContext.taskInfo On task.id Equals i.taskId Into Group
Where Group.Any()
Select task
这是您可以做的最好的一次查询。
如果这不起作用,那么您可以将tasks
和taskInfo
记录拉入内存并在那里进行过滤。只要您没有太多记录,无论如何这通常都会更快。