动态Orderby功能

时间:2015-11-10 07:01:55

标签: c# linq generics

在我的"发票"它有20多个字段,我需要支持对所有字段进行排序。

我有一个接受属性字符串的方法(例如" AmountDue")。现在我需要OrderBy AmoundDue字段。

我的具体要求是,传递一个属性名称字符串值,我想返回一个像

这样的函数

Func<Invoice, decimal> keySelector = a=> a.AmountDue;

动态构建整个表达式。

我可以使用keySelector进行排序

_api.Invoices.Find().Where(c => c.Contact.Id == contactId).OrderBy(keySelector).ToList();

到目前为止,我能够使用字符串值识别类型。需要一些帮助来返回一个函数。

  public static Type VariableType(string prop)
    {
        Type type = typeof(TResource);
        PropertyInfo pi = type.GetProperty(prop, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
        type = pi.PropertyType;
        return type;
    }
  

在发布此问题之前,我提到this post。输入是   两个问题都是相同的,但输出是不同的。一世   试图使用该解决方案并玩弄,但无法解决我的问题   具体问题。就我而言,我正在调用第三方API(Xero   api)我想专门构建这个输出。

4 个答案:

答案 0 :(得分:2)

排序时,您必须返回属性值,而不是类型属性本身

  String propertyName = "AmountDue";

  var result = _context
    .Invoices
    .Find()
    .Where(c => c.Contact.Id == contactId)
    .OrderBy(item => typeof(Invoice).GetProperty(
         propertyName, 
         BindingFlags.Public | BindingFlags.Instance)
       .GetValue(item))
    .ToList();

答案 1 :(得分:1)

您可以将对象传递给反射函数并返回相应的属性,如下所示:

.OrderBy(o => keySelector(o, propertyName))

public static Type VariableType(object o, string prop)
{
    Type type = typeof(TResource);
    PropertyInfo pi = type.GetProperty(prop, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
    return pi.GetValue(o);
}

但我不认为这会对IQueryable起作用,因为它无法将函数转换为SQL。因此,您必须先执行查询(例如使用ToList()

_context.Invoices.Find().Where(c => c.Contact.Id == contactId).ToList().OrderBy(o => keySelector(o, propertyName)).ToList();

使用dynamic LINQ作为Grundy在评论中建议可能是更好的解决方案。

答案 2 :(得分:0)

您可能还希望能够在排序方向(升序,降序)之间切换。这会带给你另一个问题。通过一些小的更改,您应该能够从this answer调整您的解决方案。

然后使用非常简单,只需在您的集合上调用Extension方法OrderBy<T>即可。这也是您正在寻找的代码片段。

答案 3 :(得分:0)

而不是反射,你可以在字典中进行简单的查找。

static readonly Dictionary<string, Func<Invoice, decimal>> keySelectors = ...;

启动时(或使用Lazy)初始化所有keySelectors:

keySelectors.Add("AmountDue", a=> a.AmountDue);
// add all 20 options here

现在每次你需要它时,它只是一个快速的字典查找。

优点:

  • 将用于连接UI和业务逻辑的字符串与字段名称分离,从而可以安全地重构它们。
  • 团队中的其他开发人员很容易理解和维护。