将表达式传递给NHibernate中的方法会导致"ConstantExpression"类型的Object无法转换为"LambdaExpression"类型

Ron*_*Ron 1 linq nhibernate expression subquery

在NHibernate 2和3中都会出现这个问题.我有一个A类,它有一个B类成员集.查询类直接执行得很好.但是当我将涉及类B的表达式之一传递给方法时,我得到以下错误:

System.ArgumentException:"System.Linq.Expressions.ConstantExpression"类型的对象无法转换为"System.Linq.Expressions.LambdaExpression"类型.

据我所知,我将完全相同的表达式传递给Any()方法.但出于某种原因,他们受到不同的待遇.我做了一些调试,看起来在第一个方法中,表达式被视为具有NodeType'Quote'的表达式,而第二个方法中的相同表达式似乎被视为具有NodeType'Constant'的表达式.第二种方法中表达式的父表达式具有NodeType"MemberAccess".所以看起来表达式树在不同的测试方法中是不同的.我只是不明白为什么以及如何解决这个问题.

课程涉及:

public class A
{
   public virtual int Id { get; set; }
   public virtual ISet<B> DataFields { get; set; }
}

public class B
{
   public virtual int Id { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

示例测试代码:

    [TestMethod]
    public void TestMethod1()
    {
        using (ISession session = sessionFactory.OpenSession())
        {
            var records = session.Query<A>()
                                 .Where<A>(a => a.DataFields
                                                 .Any(b => b.Id == 1));
            Console.Write("Number of records is {0}", records.Count());
        }
    }

    [TestMethod]
    public void TestMethod2()
    {
        GetAsWhereB(b => b.Id == 1);
    }

    private void GetAsWhereB(Func<B, bool> where) 
    {
        using (ISession session = sessionFactory.OpenSession())
        {
            var records = session.Query<A>()
                                 .Where(a => a.DataFields
                                              .Any(where));
            Console.Write("Number of records is {0}", records.Count());
        }
    }
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 5

这是一个问题:

private void GetAsWhereB(Func<B, bool> where) 
Run Code Online (Sandbox Code Playgroud)

这是一个代表 - 你想要一个表达式树,否则NHibernate无法参与其中.试试这个:

private void GetAsWhereB(Expression<Func<B, bool>> where)
Run Code Online (Sandbox Code Playgroud)

另外,由于您使用了空格,因此您的查询很难阅读.我建议不要:

var records = session.Query<A>().Where<A>(a => a.DataFields.
                                 Any(b => b.Id == 1));
Run Code Online (Sandbox Code Playgroud)

你明确表示"Any"调用是在DataFields上:

var records = session.Query<A>().Where<A>(a => a.DataFields
                                                .Any(b => b.Id == 1));
Run Code Online (Sandbox Code Playgroud)

我还建议您将参数名称从"where"更改为"whereExpression"或"predicate".某种名词,无论如何:)