2016-03-04 3 views
0

J'ai une situation où je vais devoir trier dynamiquement en fonction de la configuration de la table de base de données ascendant ou descendantC# dynamique pour LINQ par objet expando

Ma table de base de données a le nom de la colonne que je vais devoir trier et ordre de tri .

J'ai une liste d'objets, dans laquelle chaque objet a un ExpandoObject.

ma classe ressemble à ce

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

classe client a un ExpandoObject afin de stocker d'autres propriétés également appelés propriétés personnalisées qui sont configurables par client.

J'ai une table qui a des configurations pour le tri, il a les noms de colonnes et ordre de tri tels que

ColName  SortOrder 

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

Tous les noms de colonnes commençant par custom_ (Nom de) sont stockés dans l'objet expando qui Le tour est un dictionnaire.

En ce moment je suis en utilisant le code ci-dessous pour faire LINQ dynamique 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)); 
} 

Quelqu'un pourrait-il me aider sur comment pourrais-je trier les données dans l'objet personnalisé qui est de type ExpandoObject.

ExpandoObject enveloppe effectivement les propriétés comme un dictionnaire interne afin que quelqu'un pourrait me aider sur comment pourrais-je trier tout l'objet en fonction de la valeur d'un dictionnaire correspondant à une clé (qui est columnName)

Répondre

1

Vous pouvez essayer avec quelque chose comme:

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

utiliser comme:

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

Notez que vous utilisez mon OrderByCustomer aussi bien pour le premier orde anneau (où il utilise le OrderBy/OrderByDescending) et pour l'autre sous-ordre (où il utilise le ThenBy/ThenByDescending)