简体   繁体   中英

Need help to use Expression Tree to build a LINQ query

I need to build an epression tree for a LINQ query that looks something like this:

collection.OrderBy(e => ((MyObject)e["PropertyIndex"]).dictionary.Where(k => k.Key == "keyName").Select(k => k.Value).Single());

I looked at this link that explains how to chain OrderBy methods. I don't know how do I add Where inside OrderBy using Expression Tree.

Update:

I need to sort data in memory dynamically. So the linq query could look something like this:

collection.OrederBy(field1).ThenByDescending(field2).ThenBy(field3)

I know only at runtime how many fields I need to sort by. Any of fieldX can be a complex object. The type of the object of course will be known at runtime. One of the object has a structure like you see in the LINQ query above. It has a dictionary and I have to sort for a specific key. In my case dictionary contains localized data like:

{{"en-US", "word (en)"}, {"es-ES", "word (es)"} , ....}

I need to sort by specific language.

It appears your query is doing this:

from k in collection
where k.Key == "keyName"
orderby ((MyObject)k)["PropertyIndex"]
select k.Value

and you could add more where clauses like this:

from k in collection
where k.Key == "keyName"
&& k.OtherProperty == OtherValue
orderby ((MyObject)k)["PropertyIndex"]
select k.Value

EDIT : With the clarified requirements, I'd recommend you first do all your where clauses (no need to sort data you'll just ignore), then apply all the .OrderBy(). If you can make them lambdas, that's much easier than the link you suggested (pun intended):

.OrderBy( e => e.Property1 ).OrderBy( e => e.Property2 )

If you'd like to "dynamically" form these, do something like this:

var query = (from k in collection select k);
query = query.Where( e => e.Property1 == "value" );
var orderedQuery = query.OrderBy( e => e.Property1 );
orderedQuery = query.Orderby( e => e.Property2 );
var result = orderedQuery.Select( e => e.Value ).Single();

Sprinkle some conditions around these things, and you'll be golden. Note that query is of type IQueriable<T> and orderedQuery is of type IOrderedQueriable<T> , which is why you can't (without casting) reuse the same var.

You just need to apply first order field by OrderBy and all other fields by ThenBy. Of cource you have to use temporarry variable of type IOrderedEnumerable.

If you need to add some filters, then you have to add Where BEFORE any Order.

If there is many possible order options and you don't want to hardcode them, then you can use Dynamic LinQ and specify order fields as strings.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM