0

我想为我动态构建 - 子句的某个查询计算行数WHERE

让我兴奋的是我在以两种不同的方式构建它时看到的不同。

试试 1

int resultsCount = context.MyView.Where(x => x.Id > 100000).Count();

在我看到的探查器中,正在执行以下查询:

SELECT 
[GroupBy1].[A1] AS [C1]
FROM ( SELECT 
    COUNT(1) AS [A1]
    FROM (SELECT 
      [MyView].[Id] AS [Id], 
      [MyView].[EventTypeId] AS [EventTypeId], 
      [MyView].[EventSourceId] AS [EventSourceId], 
      [MyView].[TraceLevelId] AS [TraceLevelId], 
      [MyView].[TimeCreated] AS [TimeCreated], 
      [MyView].[Data1MaxStr] AS [Data1MaxStr]
      FROM [dbo].[MyView] AS [MyView]) AS [Extent1]
    WHERE [Extent1].[Id] > 100000
)  AS [GroupBy1]

试试 2

但是我必须检查多个条件,并不是每次执行都需要满足所有条件。所以我尝试WHERE为我的COUNT动态构建 - 子句(参考这篇文章):

var parameter = Expression.Parameter(typeof(MyView), "x");
Expression<Func<MyView, bool>> check1 = x => x.Id > 100000;
Expression expression = Expression.Constant(true);
expression = Expression.AndAlso(expression, Expression.Invoke(check1, parameter));
var lambda = Expression.Lambda<Func<MyView, bool>>(expression, parameter);

int resultsCount = context.MyView.Where(lambda.Compile()).Count();

我希望看到执行相同或至少类似的查询,但我在分析器中看到以下内容:

SELECT 
[Extent1].[Id] AS [Id], 
[Extent1].[EventTypeId] AS [EventTypeId], 
[Extent1].[EventSourceId] AS [EventSourceId], 
[Extent1].[TraceLevelId] AS [TraceLevelId], 
[Extent1].[TimeCreated] AS [TimeCreated], 
[Extent1].[Data1MaxStr] AS [Data1MaxStr]
FROM (SELECT 
      [MyView].[Id] AS [Id], 
      [MyView].[EventTypeId] AS [EventTypeId], 
      [MyView].[EventSourceId] AS [EventSourceId], 
      [MyView].[TraceLevelId] AS [TraceLevelId], 
      [MyView].[TimeCreated] AS [TimeCreated], 
      [MyView].[Data1MaxStr] AS [Data1MaxStr]
      FROM [dbo].[MyView] AS [MyView]) AS [Extent1]

然而的值resultsCount是相同的,但为什么这些查询如此不同,LinQ 在哪里获得COUNT第二个查询,因为我没有看到任何COUNT被选中?

有人可以告诉我如何强制执行类似于第一个但仍WHERE动态构建我的 - 子句的查询吗?

任何提示将不胜感激。

4

1 回答 1

1

你在呼唤Compile你的表情。

这将其从 aExpression<Func<MyView, bool>>转换为 a Func<MyView, bool>。由于它只是一个委托,而不是Expression,它不再匹配 的IQueryable重载的签名Where,它只匹配IEnumerable重载。

这意味着查询不会被翻译成 SQL;您正在查询没有过滤的数据,然后在 LINQ 中对客户端的对象进行过滤。

如果您希望查询提供程序将查询转换为 SQL,请务必不要编译 lambda。

于 2013-09-30T14:38:00.937 回答