Reputation: 27
I have an ObservableCollection<myListType> Items
.
Each item in Items has a Project Name which can be "Administrative" and "Non-Administrative"(can be anything). I want to sort my Items using LINQ so that the items with Non-Administrative Project Name will be put on top of Administrative item.
So far i use,
Items.OrderBy(x => x.ProjectName != "Administrative").ThenBy(x => x.ProjectName == "Administrative");
But it doesn't sort the way i want and when i debug, I saw
"The Expression not supported".
Any ideas?
Upvotes: 1
Views: 201
Reputation: 14228
You make sure ProjectName == "Administrative"
is always on the bottom.
var result = Items.OrderBy(p => p.ProjectName == "Administrative");
Upvotes: 0
Reputation: 9732
How you use OrderBy
and ThenBy
shows a lock of understanding how OrderBy
works. Please see the following example
| ID | Project Name |
-----------------------
| 1 | Administrative |
| 2 | X |
| 3 | Administrative |
| 4 | X |
With the expression x.ProjectName != "Administrative"
, OrderBy
will look at all items and sort them by whether ProjectName
is not "Administrative"
.
| ID | Project Name | ProjectName != "Administrative" |
---------------------------------------------------------
| 1 | Administrative | false |
| 2 | X | true |
| 3 | Administrative | false |
| 4 | X | true |
This will yield the following order
| ID | Project Name | ProjectName != "Administrative" |
---------------------------------------------------------
| 1 | Administrative | false |
| 3 | Administrative | false |
| 2 | X | true |
| 4 | X | true |
because true
is deemed greater by OrderBy
. ThenBy
now tries to order the groups internally, i.e. all items that matched a single "order key" are tried to be ordered by another criteria. See the following table for visualization
| ID | Project Name | ProjectName != "Administrative" |
---------------------------------------------------------
| 1 | Administrative | false | Items for false
| 3 | Administrative | false |
=========================================================
| 2 | X | true | Items for true
| 4 | X | true |
Since ProjectName == "Administrative"
has the same value for all items withing a single group, no subsequent ordering happens.
Simply use
Items.OrderBy(x => x.ProjectName == "Administrative")
Since ProjectName == "Administrative"
is true
for all administrative projects and true
is deemed greater by OrderBy
they show up last.
Upvotes: 1
Reputation: 537
According to your requirements, "Non-Administrative" should be put on top of "Administrative". You can do this:
var list = Items.OrderByDescending(x => x.ProjectName);
it will put "Non-Administrative" before "Administrative".
Edited
[for non-administrative name that has 'AAA']:
var result = Items.OrderBy(p => p.ProjectName == "Administrative").ThenBy(p => p.ProjectName);
Upvotes: 1