C#表达式组成

时间:2018-07-17 15:08:43

标签: c# lambda expression iqueryable

说我有两节课:

public class Parent {
   public Child Child { get; set; }
}

public class Child {
   public string Name { get; set; }
}

我想编写一个函数,以按包含子字符串的孩子的名字过滤父母。

public IQueryable<Parent> ParentsChildNameMatches(IQueryable<Parent> parents, string word)
{
   return parents.Where(parent => parent.Child.Name.Contains(word));
}

如果我随后想提取该表达式,以便在其他地方重用“ Child contains”支票

public Expression<Func<Child, bool> ChildNameMatches(string word)
{
   return child => child.Name.Contains(word));
}

然后我该如何在其中使用它。在哪里可以重写ParentsChildNameMatches?

public IQueryable<Parent> ParentsChildNameMatches(IQueryable<Parent> parents, string word)
{
   return parents.Where( // how to leverage ChildNameMatches?
}

2 个答案:

答案 0 :(得分:2)

因此,在给定_GLIBCXX_USE_CXX11_ABI的情况下,您可以通过Expression<Func<Child, bool>>类中的Parent属性创建从ChildChild的表达式,您想要获得一个Parent

您可以使用expression trees API手动执行此操作,也可以使用LinqKit之类的一些第三方库,如下所示:

Expression<Func<Parent, bool>>

LinqKit提供了public IQueryable<Parent> ParentsChildNameMatches(IQueryable<Parent> parents, string word) { var childExpression = ChildNameMatches(word); Expression<Func<Parent, bool>> expression = p => childExpression.Invoke(p.Child); expression = expression.Expand(); return parents.Where(expression); } 方法,使您可以一起编写表达式。它还提供了Invoke方法,可以平整结果表达式。

您可以在此处了解更多信息:http://www.albahari.com/nutshell/linqkit.aspx

更新:以前的代码无效。固定。

答案 1 :(得分:0)

您可以将lambda与Invoke

结合使用
public static IQueryable<Parent> ParentsChildNameMatches(IQueryable<Parent> parents, string word)
{
    var childPredicate = ChildNameMatches(word);

    var parent = Expression.Parameter(typeof(Parent), "parent");
    var parentPredicate = Expression.Lambda<Func<Parent, bool>>(
        Expression.Invoke(
            childPredicate, 
            Expression.Property(parent, "Child")),
        parent);

    return parents.Where(parentPredicate);
}

此代码将创建一个新表达式parent => parent.Child并将其用作childPredicate的参数