NHibernate (3.1.0.4000) NullReferenceException с использованием Query <> и NHibernate Facility - PullRequest
8 голосов
/ 05 апреля 2011

У меня проблема с NHibernate, я не могу найти решение для.В моем проекте у меня есть простая сущность (Batch), но всякий раз, когда я пытаюсь выполнить следующий тест, я получаю исключение.Я описал несколько разных способов выполнить похожий запрос, но почти одинаковое исключение для всех (различие в том, какой метод LINQ выполняется).

Первый тест:

[Test]
public void QueryLatestBatch()
{
    using (var session = SessionManager.OpenSession())
    {
        var batch = session.Query<Batch>()
            .FirstOrDefault();

        Assert.That(batch, Is.Not.Null);
    }
}

Исключение:

System.NullReferenceException : Object reference not set to an instance of an object.
at NHibernate.Linq.NhQueryProvider.PrepareQuery(Expression expression, ref IQuery query, ref NhLinqExpression nhQuery)
at NHibernate.Linq.NhQueryProvider.Execute(Expression expression)
at System.Linq.Queryable.FirstOrDefault(IQueryable`1 source)

Второй тест:

[Test]
public void QueryLatestBatch2()
{
    using (var session = SessionManager.OpenSession())
    {
        var batch = session.Query<Batch>()
            .OrderBy(x => x.Executed)
            .Take(1)
            .SingleOrDefault();

        Assert.That(batch, Is.Not.Null);
    }
}

Исключение:

System.NullReferenceException : Object reference not set to an instance of an object.
at NHibernate.Linq.NhQueryProvider.PrepareQuery(Expression expression, ref IQuery query, ref NhLinqExpression nhQuery)
at NHibernate.Linq.NhQueryProvider.Execute(Expression expression)
at System.Linq.Queryable.SingleOrDefault(IQueryable`1 source)

Однако этот тест проходит (с использованием QueryOver <>):

[Test]
public void QueryOverLatestBatch()
{
    using (var session = SessionManager.OpenSession())
    {
        var batch = session.QueryOver<Batch>()
            .OrderBy(x => x.Executed).Asc
            .Take(1)
            .SingleOrDefault();

        Assert.That(batch, Is.Not.Null);
        Assert.That(batch.Executed, Is.LessThan(DateTime.Now));
    }
}

Использование API QueryOver <> совсем не плохо, но я просто сбит с толку, что API Query <> не работает, что довольно печально, так как Первый() Операция очень лаконична, и нашим разработчикам очень нравится LINQ.

Я действительно надеюсь, что есть решение для этого, так как странно, если эти методы не проходят такой простой тест.

РЕДАКТИРОВАТЬ

Я использую Oracle 11g, мои сопоставления выполнены с помощью FluentNHibernate, зарегистрированного через Castle Windsor с помощью NHibernate Facility.Как я уже писал, странным является то, что запрос отлично работает с API QueryOver <>, но не через LINQ.

Ответы [ 2 ]

11 голосов
/ 06 апреля 2011

Существует проблема с текущей реализацией методов расширения LINQ для NHibernate 3.1.0.4000, используемых вместе с NHibernate Facility 2.0RC (и предыдущими версиями) (см .: https://nhibernate.jira.com/browse/NH-2626 и обсуждение здесь: http://groups.google.com/group/castle-project-devel/browse_thread/thread/ac90148a8d4c8477)

Исправление, которое я использую в данный момент, состоит в том, чтобы просто игнорировать методы расширения LINQ, предоставляемые NHibernate, и создавать его самостоятельно. Они на самом деле просто однострочники:

public static class NHibernateLinqExtensions
{
    /// <summary>
    /// Performs a LINQ query on the specified type.
    /// </summary>
    /// <typeparam name="T">The type to perform the query on.</typeparam>
    /// <param name="session"></param>
    /// <returns>A new <see cref="IQueryable{T}"/>.</returns>
    /// <remarks>This method is provided as a workaround for the current bug in the NHibernate LINQ extension methods.</remarks>
    public static IQueryable<T> Linq<T>(this ISession session)
    {
        return new NhQueryable<T>(session.GetSessionImplementation());
    }

    /// <summary>
    /// Performs a LINQ query on the specified type.
    /// </summary>
    /// <typeparam name="T">The type to perform the query on.</typeparam>
    /// <param name="session"></param>
    /// <returns>A new <see cref="IQueryable{T}"/>.</returns>
    /// <remarks>This method is provided as a workaround for the current bug in the NHibernate LINQ extension methods.</remarks>
    public static IQueryable<T> Linq<T>(this IStatelessSession session)
    {
        return new NhQueryable<T>(session.GetSessionImplementation());
    }
}

Затем, когда мне нужно выполнить запрос LINQ, я просто использую session.Linq<EntityType>() вместо session.Query<EntityType>.

Надеюсь, это поможет кому-то в той же ситуации, что и я.

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

Я нашел следующее: http://groups.google.com/group/castle-project-users/browse_thread/thread/5efc9f3b7b5d6a08

Очевидно, что есть проблема с текущей версией NHibernate Facility и NHibernate 3.1.0.4000.

Полагаю, мне просто нужно подождать, пока исправление:)

...