2016-03-04 3 views
0

У меня есть ситуации, когда мне нужно будет сортировать динамически на основе конфигурации из таблицы базы данных по возрастанию или по убываниюC# Динамический порядок LINQ по объекту EXPANDO

Моей таблицы базы данных имеет имя столбца, что мне нужно будет сортировать и порядок сортировки ,

У меня есть список объектов, в которых каждый объект имеет объект 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(); 
} 

класс Клиент имеет ExpandoObject для того, чтобы сохранить дополнительные свойства также называемые как пользовательские свойства, которые могут быть сконфигурированы для каждого клиента.

У меня есть таблица, которая имеет конфигурацию для сортировки, то есть имена столбцов и порядок сортировки , такие как

ColName  SortOrder 

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

Все имена столбцов, начиная с custom_ (Имя свойства) хранятся в объекте EXPANDO, которые в turn - это словарь.

Прямо сейчас я использую следующий код, чтобы сделать динамический 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 фактически упаковывает свойства как словарь внутри, так может кто-нибудь помочь мне о том, как я мог сортировать весь объект на основе значения словаря соответствующего ключа (который ColumnName)

ответ

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 как для первого Orde (где используется OrderBy/OrderByDescending) и для другого подзаказа (где он использует ThenBy/ThenByDescending)

Смежные вопросы