3

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.

Community
  • 1
  • 1
Vadim
  • 19,585
  • 14
  • 61
  • 100
  • 1
    Can you explain exactly what it is your are trying to achieve data-wise? There could be a simpler solution :) – mattytommo May 16 '12 at 18:56

2 Answers2

1

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.

robrich
  • 12,467
  • 5
  • 30
  • 57
  • 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. – Vadim May 16 '12 at 19:02
  • It's not an option for me. I need to build an Expression Tree. I also solved my problem. I created a function on 'e' object which I call using reflection in my expression tree. But thanks for your answer. You definitively deserve +1. I'll put my solution here tomorrow. – Vadim May 17 '12 at 01:14
0

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.

Tom Kris
  • 1,217
  • 1
  • 8
  • 14