0

我今天注意到,如果我这样做:

var items = context.items.Where(i => i.Property < 2);
items = items.Where(i => i.Property > 4);

一旦我访问 items var,它只执行第一行作为数据调用,然后在内存中进行第二次调用。但是,如果我这样做:

var items = context.items.Where(i => i.Property < 2).Where(i => i.Property > 4);

我只得到一个针对包含两个 where 语句的上下文执行的表达式。我有许多变量,我想用它们来构建 linq lambda 的表达式,但是它们的存在或不存在会改变表达式,因此我必须有大量的条件来满足所有情况。我想我可以像上面的第一个示例一样添加 Where() 语句,但这不会以包含所有条件的单个表达式结束。因此,我试图只创建 lambda 本身:

//bogus syntax
if (var1 == "something")
    var expression = Expression<Func<item, bool>>(i => i.Property == "Something);
if (var2 == "somethingElse")
    expression = expression.Where(i => i.Property2 == "SomethingElse");

然后将其传递到我的 context.Items 的位置进行评估。A)这是对的,B)如果是这样,你是怎么做的?

编辑:

IQueryable assessments = assessmentContext.Assessments;
metAssessments = metAssessments.Take(pageSize);

结果是

SELECT [Fields] <== edited
FROM [dbo].[Assessment] AS [t0]
INNER JOIN [dbo].[AssessmentComment] AS [t1] ON [t1].[ID] = [t0].[AssessmentID] <== because of load options

为什么没有 top x(以 pageSize 表示)?

4

3 回答 3

2

您使用的是什么查询提供程序?Where对于任何合理的提供者,您的第一个示例应该在源(而不是内存)上执行,作为您每个s中两个条件的结合。

至于您的问题,不,这不是继续Expression手动构建的正确方法。您的第一个定义很好,但要建立一个连词,您需要使用Expression.AndAlso.

人们已经将它包装到一个库中供您使用。请参阅PredicateBuilder

于 2011-01-03T16:53:49.213 回答
0

使用PredicateBuilder动态构建查询。

于 2011-01-03T16:54:31.333 回答
0

我想第一个和第二个不同的原因是当时items已经访问了数据。如果您使items对象继承自IQueryable您,则在您实际访问集合中的项目之前,您实际上不会针对上下文执行任何操作。

于 2011-01-03T16:55:20.910 回答