将lambda传递给Where语句

时间:2011-01-03 16:51:14

标签: linq linq-to-sql lambda expression linq-expressions

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

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

一旦我访问了项目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

为什么没有顶部x(由pageSize表示)?

3 个答案:

答案 0 :(得分:2)

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

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

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

答案 1 :(得分:0)

使用PredicateBuilder动态构建查询。

答案 2 :(得分:0)

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