user7951164
user7951164

Reputation:

OrderByDescending in lambdaExpression is not accepting parameters

Below is my code , i am trying to get distinct sub keys in descending order All is well but in OrderByDescending it is not suggesting field

 List<string> Sub_key_list = dt
   .AsEnumerable()
   .Select(d => d.Field<string>("Sub_Key_Name"))
   .Distinct()
   .OrderByDescending(e => e.not suggesting field here )
   .ToList();

Am i writing it wrong ?

Upvotes: 0

Views: 117

Answers (3)

Sonu
Sonu

Reputation: 25

First of all i doubt if it works d.Field("Sub_Key_Name") ?

I create a simple example of list of strings and then sorting :

var list = new List<string>();
        list.Add("a");
        list.Add("ab");
        list.Add("ab");
        list.Add("abc");
        list.Add("lmn");
        list.Add("xyz");

        var q = list.AsEnumerable().Select(s => s).Distinct().OrderByDescending(s => s).ToList();

        foreach(var i in q)
        {
            Console.WriteLine(i);
        }

It works fine.

Upvotes: 0

Peter Duniho
Peter Duniho

Reputation: 70691

According to one comment:

OP is expecting the same intellisense behavior like two rows above where he select a field from a datatable - but at that point there is no more datatable, just string

That is, you want to be able to order by some field in your data row other than the one you are selecting for the Distinct() operation. I think that gets a little complicated, but it's doable.

Unfortunately, the Distinct() method returns an unordered sequence. I.e. you can't do your ordering first and then use Distinct(). This prevents us from being able to extract into an anonymous type the fields we care about for ordering and the final value, ordering that data, and then using Distinct() on the result.

On the other hand, without a custom equality comparer implementation, Distinct() will apply its logic to the entire object, rather than just one field (there's not an overload that lets you select a value for the operation). So we would need to provide a custom equality comparer, which is still doable with anonymous types, but gets even more complicated.

There is also a logical issue: the Distinct() operation necessarily will reduce several rows with the same value into just one. This results in there just being one ordering field value, from the potentially many that were there, but you don't get to pick which one.

Fortunately, all of the above can be addressed using GroupBy() instead of Distinct(). With GroupBy(), you can initially select an anonymous type containing the fields of interest, then group them by a specific key (the "Sub_Key_Name" value in this case), but without losing any of the ordering fields. You can then pick from the ordering fields using whatever logic makes sense in your application (your question doesn't specify, so for this example, I just use the maximum value), and use that value to actually order the results. Finally, selecting just the grouping key gets you the final value you wanted.

That would look something like this:

List<string> Sub_key_list = dt
   .AsEnumerable()
   .Select(d => new
   {
       OrderKey = d.Field<int>("OrderKey"), // i.e. whatever you want here
       Value = d.Field<string>("Value"),
   })
   .GroupBy(e => e.Value)
   .OrderByDescending(e => e.Max(x => x.OrderKey)) // I used Max...use whatever you want
   .Select(e => e.Key)
   .ToList();


For additional inspiration, see also related/similar questions:
Linq orderby and distinct
Select Multiple Fields from List in Linq
Distinct in Linq based on only one field of the table

Upvotes: 0

Patrick Hofman
Patrick Hofman

Reputation: 157048

The argument passed to OrderByDescending is an IEnumerable<string>, so e is your string here. That means you can simply order by e like this:

.OrderByDescending(e => e)

Upvotes: 3

Related Questions