使用Query<>的NHibernate(3.1.0.4000)NullReferenceException和NHibernate工厂

时间:2011-04-05 08:52:54

标签: nhibernate oracle11g castle-windsor linq-to-nhibernate windsor-nhfacility

我有NHibernate的问题,我似乎无法找到任何解决方案。 在我的项目中,我有一个简单的实体(批处理),但每当我尝试运行以下测试时,我都会遇到异常。 我已经尝试了几种不同的方法来执行类似的查询,但几乎完全相同的异常(它与执行的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&lt;&gt;):

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

使用QueryOver&lt;&gt; API一点都不差,但我有点困惑的是查询&lt;&gt; API不起作用,这有点令人难过,因为First()操作非常简洁,我们的开发人员真的很喜欢LINQ。

我真的希望有一个解决方案,因为如果这些方法没有通过如此简单的测试,这似乎很奇怪。

修改

我正在使用Oracle 11g,我的映射是通过使用NHibernate Facility在Castle Windsor注册的FluentNHibernate完成的。 正如我所写,奇怪的是查询与QueryOver&lt;&gt;完美配合。 API,但不是通过LINQ。

2 个答案:

答案 0 :(得分:11)

NHibernate 3.1.0.4000的LINQ扩展方法的当前实现存在一个问题,该方法与NHibernate Facility 2.0RC(和以​​前的版本)一起使用(参见:https://nhibernate.jira.com/browse/NH-2626并在此讨论:http://groups.google.com/group/castle-project-devel/browse_thread/thread/ac90148a8d4c8477

我目前使用的修复方法是简单地忽略NHibernate提供的LINQ扩展方法并自己创建它。他们真的只是单行:

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>

希望它可以帮助处于同样情况的人。

答案 1 :(得分:0)

我找到了以下内容:http://groups.google.com/group/castle-project-users/browse_thread/thread/5efc9f3b7b5d6a08

显然当前版本的NHibernate Facility和NHibernate 3.1.0.4000存在问题。

我想我只需等待修复:)