开发者

Passing in a lambda to a Where statement

I noticed today that if I do this:

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

Once I access the items var, it executes only the first line as the data call and then does the second call in memory. However, if I do this:

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

I get only one expression executed against the context that includes both where statements. I have a host of variables that I want to use to build the expression for the linq lambda, but their presence or absence changes the expression such that I'd have to have a rediculous number of conditionals to satisfy all cases. I thought I could just add the Where() statements as in my first example above, but that doesn't end up in a single expression that contains all of the criteria. Therefore, I'm trying to create just the lambda itself as such:

//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");

And then pass that in to the where of my context.Items to evaluate. A) is this right, and B) if so, how do you do it?

EDIT:

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

results in

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

Why no top x (as represented by pageSize)?


What query provider are you using? For any reasonable provider, your first example should execute on the source (not in memory) as the conjunction of the two conditions in each of your Wheres.

As for your question, no, that's not the right way to proceed to build an Expression manually. Your first definition is fine, but to build a conjunction you need to use Expression.AndAlso.

People have already wrapped this into a library for your usage. See PredicateBuilder.


Use the PredicateBuilder to construct your query dynamically.


I would imagine that the reason that the first and second differ is that items has already accessed the data at that point. If you make the items object inherit from IQueryable you won't actually execute anything against the context until you actually access the items in the collection.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜