Reputation: 10402
I have a LINQ to object query to select all the persons that are above 20 years old
IEnumerable<Object> result = null;
result = (from person in AllPersons.ToList()
where person.age > 20
select new
{
FirstName= person.FirstName,
LastName= person.LastName,
Email= person.Email,
PhoneNumber= person.PhoneNumber
});
return result;
I have a parameter string SortProperty
I want to use to sort the result based on the property.
So for example if SortProperty="FirstName"
I want to sort the result based on the first name.
I tried to do the following:
return result.OrderBy(x => x.GetType().GetProperty(SortProperty));
but it did not work
any idea how to do it?
PS: I don't want to test all the possibilities, and do a if-else on each, or a case switch. I'm looking for an efficient way to do this
Thanks
Upvotes: 1
Views: 5927
Reputation: 2869
I'm using something like this :
var sortExpression = @"A,C";
var expressions = sortExpression.Split(new[] { ',' });
var cmpPredicates = new Dictionary<string, Func<Person, Person, int>>(3);
cmpPredicates.Add(@"A", (x, y) => x.A.CompareTo(y.A));
cmpPredicates.Add(@"B", (x, y) => x.B.CompareTo(y.B));
cmpPredicates.Add(@"C", (x, y) => x.C.CompareTo(y.C));
cmpPredicates.Add(@"Default", (x, y) => x.Id.CompareTo(y.Id));
var currentPredicates = new Func<Person, Person, int>[expressions.Length + 1];
for (int i = 0; i < expressions.Length; i++)
{
currentPredicates[i] = cmpPredicates[expressions[i]];
}
// Default sort order
currentPredicates[currentPredicates.Length - 1] = cmpPredicates[@"Default"];
persons.Sort((x, y) =>
{
var cmp = 0;
var index = 0;
while (cmp == 0 && index < currentPredicates.Length)
{
cmp = currentPredicates[index++](x, y);
}
return cmp;
});
where the Person class has the following definition
public class Person
{
public string A { get; set; }
public string B { get; set; }
public string C { get; set; }
public long Id { get; set; }
public Person()
{
this.A = string.Empty;
this.B = string.Empty;
this.C = string.Empty;
}
}
The main benefit is the multiproperty support. With additional checks(duplicates & exist & predicate limit) is can be user provided.
Upvotes: 0
Reputation: 3348
Try
return result.OrderBy(x => x.GetType().GetProperty(SortProperty).GetValue(x, null));
Upvotes: 1
Reputation: 12705
return result.OrderBy( x => TypeHelper.GetPropertyValue( x, sortProperty ) )
.ToList();
Upvotes: 0
Reputation: 44268
Check out the Dynamic Linq Extensions Libraries...
It has extension Methods which accept string
s instead of Properties.
Since your SortProperty
is already a string
you could do
var result = (from person in AllPersons.ToList()
where person.age > 20
select new
{
FirstName= person.FirstName,
LastName= person.LastName,
Email= person.Email,
PhoneNumber= person.PhoneNumber
}
).OrderBy(SortProperty);
return result;
Also, depending on what AllPersons
is, it might not make sense to Enumerate that by calling ToList()
until the end. e.g.
var result = (from person in AllPersons
...
).OrderBy(SortProperty).ToList();
Upvotes: 2