C# 通过 expando 对象进行动态 linq 排序
C# Dynamic linq order by expando object
我有一种情况需要根据数据库的配置动态排序 table 升序或降序
我的数据库table有我需要排序的列名。
我有一个对象列表,其中每个对象都有一个 ExpandoObject。
我的Class看起来像这样
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();
}
客户 class 有一个 ExpandoObject 以存储额外的属性,也称为自定义属性,可按客户配置。
我有一个 table,它有排序配置,它有列名和排序顺序
比如
ColName SortOrder
City Asc
Name Desc
custom_XYZ Asc //this means this is a custom column
所有以 custom_(属性 Name) 开头的列名都存储在 expando 对象中,而 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 实际上在内部将属性包装为字典,所以有人可以帮助我如何根据对应于键(即 columnName)的字典的值对整个对象进行排序
你可以试试这样的东西:
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
)和其他子排序(使用 ThenBy
/ThenByDescending
)
我有一种情况需要根据数据库的配置动态排序 table 升序或降序
我的数据库table有我需要排序的列名。
我有一个对象列表,其中每个对象都有一个 ExpandoObject。
我的Class看起来像这样
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();
}
客户 class 有一个 ExpandoObject 以存储额外的属性,也称为自定义属性,可按客户配置。
我有一个 table,它有排序配置,它有列名和排序顺序 比如
ColName SortOrder
City Asc
Name Desc
custom_XYZ Asc //this means this is a custom column
所有以 custom_(属性 Name) 开头的列名都存储在 expando 对象中,而 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 实际上在内部将属性包装为字典,所以有人可以帮助我如何根据对应于键(即 columnName)的字典的值对整个对象进行排序
你可以试试这样的东西:
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
)和其他子排序(使用 ThenBy
/ThenByDescending
)