C#Dynamic linq order by expando object

时间:2016-03-04 19:49:48

标签: c# .net linq c#-4.0 expandoobject

我有一种情况需要根据数据库表中的升序或降序动态进行动态排序

我的数据库表具有列名称,我需要对其进行排序和排序。

我有一个对象列表,其中每个对象都有一个ExpandoObject。

我的班级看起来像这样

  public class Customer: Base {
    public string Name { get; set;}
    public string City { get; set;}
    public string Address { get; set;}
    public string State { get; set;}
    public int Id { get; set;}
    public DateTime Dob { get; set;}
    public int Age{ get; set;}
    public dynamic custom = new ExpandoObject();
 } 

Customer类有一个ExpandoObject,用于存储其他属性,也称为自定义属性,可根据客户进行配置。

我有一个包含排序配置的表,它有列名和排序顺序 比如

ColName     SortOrder

City        Asc
Name        Desc
custom_XYZ  Asc   //this means this is a custom column 

所有以custom_(Property Name)开头的列名都存储在expando对象中,而该对象又是一个字典。

现在我正在使用以下代码执行动态linq orderBy

var sortList; // this list has the sorting list with type {string:ColName: bool:Asc}
var customers; //holds the list of customer objects with custom fields in expando

var col = sortList[0];
var propertyInfo = typeof(Student).GetProperty(col.ColName);    
var sortedData= customers.OrderBy(x => propertyInfo.GetValue(x, null));

for(int i = 1; i<sortList.Count()-1;i++){
  var col1 = sortList[i];
  var prop = typeof(Student).GetProperty(col1.ColName); 
  if(col1.asc)   
    sortedData = sortedData.ThenBy(n => param2.GetValue(n, null));
  else
    sortedData = sortedData.ThenByDescending(n => param2.GetValue(n, null));
}

有人可以帮助我如何在自定义对象中对数据进行排序,该对象的类型为ExpandoObject。

ExpandoObject实际上在内部将属性包装为一个Dictionary,所以有人可以帮助我如何根据与Key对应的Dictionary的值(即columnName)对整个对象进行排序

1 个答案:

答案 0 :(得分:1)

您可以尝试使用以下内容:

public static IOrderedEnumerable<Customer> OrderByCustomer(IEnumerable<Customer> enu, Column column)
{
    Func<Customer, object> selector;

    if (!column.ColName.StartsWith("custom_"))
    {
        var propertyInfo = typeof(Customer).GetProperty(column.ColName);
        selector = x => propertyInfo.GetValue(x, null);
    }
    else
    {
        selector = x =>
        {
            object obj;
            ((IDictionary<string, object>)x.custom).TryGetValue(column.ColName.Substring("custom_".Length), out obj);
            return obj;
        };
    }

    IOrderedEnumerable<Customer> ordered = enu as IOrderedEnumerable<Customer>;

    if (ordered == null)
    {
        if (column.SortOrder == SortOrder.Asc)
        {
            return enu.OrderBy(selector);
        }
        else
        {
            return enu.OrderByDescending(selector);
        }
    }

    if (column.SortOrder == SortOrder.Asc)
    {
        return ordered.ThenBy(selector);
    }
    else
    {
        return ordered.ThenByDescending(selector);
    }
}

使用它像:

var sortedList = new[] { 
    new Column { ColName = "Name", SortOrder = SortOrder.Asc },
    new Column { ColName = "custom_Secret", SortOrder = SortOrder.Asc },
};

var col = sortedList[0];

var sortedData = OrderByCustomer(customers, sortedList[0]);

for (int i = 1; i < sortedList.Length; i++)
{
    sortedData = OrderByCustomer(sortedData, sortedList[i]);
}

var result = sortedData.ToArray();

请注意,您使用我的OrderByCustomer作为第一个排序(使用OrderBy / OrderByDescending)和其他子排序(使用{{1 }} / ThenBy