LINQ:根据参数对列表进行排序

时间:2012-05-18 08:45:57

标签: c# sorting ienumerable linq-to-objects

我有一个LINQ to对象查询来选择所有20岁以上的人

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;

我有一个参数string SortProperty我想用它来根据属性对结果进行排序。

例如,如果SortProperty="FirstName"我想根据名字对结果进行排序。

我尝试执行以下操作:

return result.OrderBy(x => x.GetType().GetProperty(SortProperty));

但它无效

任何想法怎么做?

PS:我不想测试所有可能性,并在每个或者一个案例开关上做一个if-else。我正在寻找一种有效的方法来做到这一点

谢谢

4 个答案:

答案 0 :(得分:2)

查看Dynamic Linq Extensions Libraries ...

它有扩展方法,接受string而不是属性。

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

由于您的SortProperty已经是string,您可以

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;

此外,根据AllPersons的内容,通过调用ToList()直到结束来枚举它可能没有意义。 e.g。

var result = (from person in AllPersons
             ...
             ).OrderBy(SortProperty).ToList();

答案 1 :(得分:1)

尝试

return result.OrderBy(x => x.GetType().GetProperty(SortProperty).GetValue(x, null));

答案 2 :(得分:0)

return result.OrderBy( x => TypeHelper.GetPropertyValue( x, sortProperty ) )
           .ToList();

答案 3 :(得分:0)

我正在使用这样的东西:

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;
                });

其中Person类具有以下定义

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;
        }
    }

主要好处是多属性支持。可以由用户提供额外的检查(重复和存在以及谓词限制)。