Передача выражения в метод в NHibernate приводит к тому, что объект типа 'ConstantExpression' не может быть преобразован в тип 'LambdaExpression' - PullRequest
1 голос
/ 19 января 2011

Эта проблема возникает как в NHibernate 2, так и в 3. У меня есть класс A, у которого есть набор членов класса B. Запросы к классам выполняются напрямую. Но когда я передаю одно из выражений класса B в метод, я получаю следующую ошибку:

System.ArgumentException: объект типа 'System.Linq.Expressions.ConstantExpression' нельзя преобразовать в тип 'System.Linq.Expressions.LambdaExpression'.

Насколько я вижу, я передаю точно такое же выражение в метод Any (). Но почему-то к ним относятся по-разному. Я провел некоторую отладку, и похоже, что в первом методе выражение обрабатывается как выражение с NodeType 'Quote', в то время как то же выражение во 2-м методе, похоже, рассматривается как выражение с 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; }
}

Пример тестового кода:

    [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());
        }
    }

Ответы [ 2 ]

5 голосов
/ 19 января 2011

Это одна проблема:

private void GetAsWhereB(Func<B, bool> where) 

Это займет делегат - вам нужно дерево выражений , иначе NHibernate не сможет принять участие Попробуйте это:

private void GetAsWhereB(Expression<Func<B, bool>> where)

Кроме того, ваш запрос трудно читать из-за использования пробелов. Я бы предложил вместо:

var records = session.Query<A>().Where<A>(a => a.DataFields.
                                 Any(b => b.Id == 1));

вы даете понять, что вызов "Any" находится в полях данных:

var records = session.Query<A>().Where<A>(a => a.DataFields
                                                .Any(b => b.Id == 1));

Я бы также предложил изменить имя параметра с «где» на что-то вроде «whereExpression» или «предиката». В любом случае, какое-то существительное:)

0 голосов
/ 18 апреля 2011

Не совсем уверен, правильное ли это решение или нет.Проблема ощущается как ошибка, а мое решение - как обходной путь.Тем не менее, для меня работает следующее, которое сводится к созданию «копии» данного выражения с использованием его тела и параметра для создания нового выражения.

...