c# - 如何组合两个表达式?

标签 c# linq linq-to-nhibernate

我正在尝试构建一个将应用于 IQueryable 集合的表达式。

我可以这样构建一个表达式:

[TestClass]
public class ExpressionTests
{
    private IQueryable<MyEntity> entities;

    private class MyEntity
    {
        public string MyProperty { get; set; }
    }

    [TestInitialize]
    public void Setup()
    {
        entities = new[]
                    {
                        new MyEntity {MyProperty = "first"}, 
                        new MyEntity {MyProperty = "second"}
                    }.AsQueryable();
    }

    [TestMethod]
    public void TestQueryingUsingSingleExpression()
    {
        Expression<Func<MyEntity, bool>> expression = e => e.MyProperty.Contains("irs");
        Assert.AreEqual(1, entities.Where(expression).Count());
    }
}

现在我想把表达式的两部分分开:

[TestMethod]
public void TestQueryingByCombiningTwoExpressions()
{
    Expression<Func<MyEntity, string>> fieldExpression = e => e.MyProperty;
    Expression<Func<string, bool>> operatorExpression = e => e.Contains("irs");
    // combine the two expressions somehow...
    Expression<Func<MyEntity, bool>> combinedExpression = ???;

    Assert.AreEqual(1, entities.Where(combinedExpression).Count());
}

关于如何执行此操作有什么建议吗?

顺便说一句,将解析表达式的提供程序是 NHibernate 的 Linq。

最佳答案

看看你的两个表达式树:

                 |                                      |
               Lambda                                Lambda
              /      \                              /      \
             /        \                            /        \
     Property          Parameter x               Call        Parameter y
    /        \                                  /  |  \
   /          \                                /   |   \
  x           MyProperty              EndsWidth    y    Constant
                                                        |
                                                       "5"

您需要创建一个如下所示的新树:

                                 |
                               Lambda
                              /      \
                             /        \
                           Call        Parameter z
                          /  |  \
                         /   |   \
                   EndsWith  |   Constant
                             |         \
                          Property     "5"
                         /        \
                        /          \
                       z          MyProperty

您可以很容易地看到新树的哪些部分来自哪棵原始树。

要创建树,您需要第二个 lambda 表达式(Call)的主体,并将所有出现的 y 替换为第一个 lambda 表达式(Property)的主体和所有出现的 xz。然后将结果包装在一个带有参数 z 的新 lambda 表达式中。

您可以使用 ExpressionVisitor Class重写树,以及 Expression.Lambda Method创建新的 lambda 表达式。

关于c# - 如何组合两个表达式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6854746/

相关文章:

c# - WCF 服务为某些类型抛出异常

c# - 从类库项目启动 WPF 窗口

c# - Visual Studio 中的代码分析问题

c# - LINQ to entities Query 以随机化行选择

c# - 使用 linq 到 nhibernate 时未实现方法或操作

Linq to NHibernate 和 Dynamic LINQ - 查询缓存不工作

c# - 选择第 n 个重复行之后的下一行

c# - 有没有一种优雅的方式来重复一个 Action ?

c# - 如何根据多个条件并使用 linq 从通用列表中删除项目

nhibernate - Basic Fluent NHibernate 程序编译并运行,但没有保存到数据库或从数据库加载任何内容