如何使用动态linq按表达式"prefix"顺序



在这个场景中我需要"by pass"将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");

问题是,为了使其正常工作,我必须考虑到按表达式排序的NestedProp,这将需要在我不完全控制的源代码中进行太多重构,只是为了使排序立即工作。

的例子:

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

问题是,有没有办法告诉动态Linq用NestedProp作为表达式的前缀,这样我就可以通过直接在表达式上提供子属性并将排序直接传递给NestedProp来进行排序?

像这样:

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

下面是一些使用反射自动为嵌套属性名添加前缀的代码。可以进行扩展以自动提取(多个)嵌套属性。这段代码假设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.$&"));
}

最新更新