简体   繁体   中英

Dynamic Linq “OrderBy” on runtime values

I've been looking at Dynamic Linq today (installed into VS via NuGet)...but all the examples I have found so far assume OrderBy is to be done on a known property or column name; however I am trying to OrderBy a field which is not strongly typed; but actually a key value of a row object which is derived from a Dictionary; eg

class RowValues : Dictionary<string, string>
{
...
}

So the list to be ordered is specifically a list of RowValues objects, filled with Name,Value pairs. For a given list of RowValues, the OrderBy field could by any of keys of the named value pairs entries (fyi: I want the orderby field to be specified in an xml config file ultimately so the ordering can be changed without re-deployment of binaries etc).

I've got a hunch the solution lies in writing a custom ordering function passed to the OrderBy??? This function would obviously know how to get a specific value from the RowValues object given a field name from the xml config....?? The answers I have seen so far show passing a string which contains a custom order by clause into the OrderBy, which is close to where I want to be, but how in my case would the runtime know where to find the fields referred to in the OrderBy string??

Input will be very much appreciated, or have I completely misunderstand the Dynamic Linq functions?

If you're using dynamic LINQ, it would just be:

var sortColumn = GetConfigValue(...);
var sorted = RowValues.OrderBy(sortColumn);

You could of course use a concatenated string to create a multiple sort ( "column1, column2 DESC" ). As far as I'm aware, there's no custom sort function unless you're using regular LINQ.

Also, I would make sure you know the performance characteristics of Dynamic LINQ.


Edit:

Is this what you're looking for? This will order it based on the value of the "Key" entry in the dictionary. If you need multiple sort by-s, you can use it in a loop with .ThenBy()

void Main()
{
    List<RowValues> v = new List<RowValues>();
    var key = "Key"; //GetFromConfig();

    var v1 = new RowValues();
    v1.Add("Key", "1");
    v1.Add("3", "5");

    var v2 = new RowValues();
    v2.Add("Key", "3");
    v2.Add("2", "2");

    var v3 = new RowValues();
    v3.Add("Key", "2");
    v3.Add("2", "2");

    v.Add(v1);
    v.Add(v2);
    v.Add(v3);

    v.OrderBy(r => r[key]).Dump();
}

class RowValues : Dictionary<string, string>
{

}

Kyle, thanks again. Apologies for late reply, I have moved on from this issue now but out of interest and courtesy I wanted to come back and agree your code is much closer to where I wanted to get to, but we have lost the dynamic linq aspect. So, where you are calling the OrderBy and ordering on the key, I would want to pass a string containing the order command eg "r[key] desc". The reason being I would want to leave the determination as to which direction to order until runtime. I suspect ths would be accomplished using an expression tree possibly? eg: here

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