【问题标题】:How to "prefix" order by expression using dynamic-linq如何使用dynamic-linq通过表达式“前缀”顺序
【发布时间】:2021-02-15 16:52:59
【问题描述】:

所以我有这种情况,我需要将OrderBy 表达式“绕过”到嵌套属性中,但我不能简单地更改表达式,因为它在太多地方使用而不涉及嵌套属性。

例如,我有这两个类用于生成IQueryable<Parent>,并使用.OrderBy("Title DESC") 应用订单等。但是"Title DESC"这个表达式是由外界提供的,重构起来非常困难。

class Parent {
  public Nested NestedProp {get;set;}
  /* other irrelevant props */
}

class Nested {
  public string Id {get;set;}
  public string Title {get;set;}
  public DateTime CreatedAt {get;set;}
  /* other irrelevant props */
}

我通过这样的方法恢复它:

public IQueryable<Parent> GetParentsOrdered(stirng order){
    IQueryable<Parent> query = QueryParents();
    
    return query.OrderBy(order);
}

用法是这样的:

var listOfParents = GetParentsOrdered("Title DESC");

问题是,为了让它正常工作,我必须考虑到 order by 表达式中的 NestedProp,这需要在我无法完全控制的源中进行太多重构,只是为了让订单立即生效。

例子:

var listOfParents = GetParentsOrdered("Nested.Title DESC");

问题是,有没有办法告诉 Dynamic Linq 在表达式前面加上 NestedProp,这样我就可以通过直接在表达式上提供孩子的属性并将排序直接传递给 NestedProp ?

类似这样的:

query.OrderByPrefixed("NestedProp", "Title DESC, CreatedAt DESC");

【问题讨论】:

  • 不,您需要在每个属性上指定前缀。你可以通过一些字符串操作来做到这一点,但它很脆弱。如果您想按父属性排序,然后按嵌套属性排序怎么办?为什么不能让调用者传入正确的字符串?或者更好的是,不要使用动态 Linq 并传入正确的 Expression
  • 谢谢@DavidG,感谢您的意见。为了给你更多关于这个主题的离题细节,有人滥用了动态 linq 表达式很容易使用的事实,并允许客户端 [js, angular, react] 为数据表提供排序表达式。问题是,他们没有考虑嵌套属性,这意味着没有任何排序因此而起作用。我正在尝试寻找其他方法来允许此排序至少暂时起作用,而不必重构使用它的客户端。
  • 当模式和查询本身的性质不需要动态查询时,这正是您应该使用静态类型查询而不是动态类型查询的原因。
  • 好吧,动态查询正好适合这个,问题是他们没有正确实现它所以现在我必须拦截使用并修复它以使系统工作:/
  • 所以客户端字符串被直接传递到动态 Linq 命令中?哎呀,这很危险,我会立即重写。

标签: c# linq entity-framework-core dynamic-linq


【解决方案1】:

这是一些使用反射自动为嵌套属性名称添加前缀的代码。可以进行扩展以自动提取(多个)嵌套属性。此代码假定 ParentNested 之间的属性名称没有重叠。

static List<string> NestedPropertyNames = typeof(Nested).GetProperties().Select(pi => pi.Name).ToList();
static Regex srcPattern = new Regex(@"(?<=\W|^)(?:"+String.Join("|", NestedPropertyNames)+@")(?=\W|$)", RegexOptions.Compiled);

public IQueryable<Parent> GetParentsOrdered(string order){
    IQueryable<Parent> query = QueryParents();

    return query.OrderBy(srcPattern.Replace(order, "NestedProp.$&"));
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-02
    • 2017-02-10
    • 1970-01-01
    • 2015-03-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多