我今天注意到,如果我这样做:
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表示)?
答案 0 :(得分:2)
您使用的是哪个查询提供程序?对于任何合理的提供者,您的第一个示例应该在源(而不是在内存中)执行,作为每个Where
中两个条件的结合。
至于你的问题,不,这不是手动建立Expression
的正确方法。您的第一个定义很好,但要构建一个连词,您需要使用Expression.AndAlso
。
人们已经将它包装到一个库中供您使用。请参阅PredicateBuilder。
答案 1 :(得分:0)
使用PredicateBuilder动态构建查询。
答案 2 :(得分:0)
我认为第一个和第二个不同的原因是items
已经在那时访问了数据。如果使items
对象继承自IQueryable
,则在实际访问集合中的项之前,实际上不会对上下文执行任何操作。