C#通过expando对象的动态LINQ顺序 [英] C# Dynamic linq order by expando object

查看:134
本文介绍了C#通过expando对象的动态LINQ顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个情况,我需要根据数据库表升序或降序的配置动态排序



我的数据库表有列名我需要排序和排序顺序。



我有一个对象列表,其中每个对象都有一个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
名称Desc
custom_XYZ Asc //这意味着这是一个自定义列

以custom_(属性名称)开头的所有列名称都存储在expando对象中是一个字典。



现在我使用下面的代码来做动态的linq orderBy

  var sortList; //此列表具有类型为{string:ColName:bool:Asc}的排序列表
var customers; //保存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实际上将属性作为一个字典内部包装,所以有人可以帮助我如何基于对应于一个字典的值排序整个对象

$ p









  public static IOrderedEnumerable< Customer> OrderByCustomer(IEnumerable< Customer> enu,Column column)
{
Func< Customer,object>选择器

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 )和其他子排序 ThenBy / ThenByDescending


I have a situation where I will need to sort dynamically based on a configuration from database table ascending or descending

My Database table has column name That I will need to sort and sort order.

I have a list of objects, in which each object has an ExpandoObject.

My Class looks like this

  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 class has an ExpandoObject in order to store additional properties also called as custom properties which are configurable per Customer.

I have a table which has configurations for sorting, it has the Column names and sort order such as

ColName     SortOrder

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

All the column names starting with custom_(Property Name) are stored in expando object which in turn is a dictionary.

Right now I am using the below code to do dynamic 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));
}

could someone help me on how could I sort data in custom object which is of type ExpandoObject.

ExpandoObject actually wraps the properties as a Dictionary internally so could someone help me on how could I sort the whole object based on the value of a Dictionary corresponding to a Key (which is columnName)

解决方案

You could try with something like:

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

use it like:

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

Note that you use my OrderByCustomer both for the first ordering (where it uses the OrderBy/OrderByDescending) and for the other sub-ordering (where it uses the ThenBy/ThenByDescending)

这篇关于C#通过expando对象的动态LINQ顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆