8

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)

2番目のテスト:

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

QueryOver <> APIの使用はまったく悪いことではありませんが、First()操作が非常に簡潔であるため、Query <> APIが機能していないことに少し戸惑っています。これは、ちょっと悲しいことです。 LINQを本当に楽しんでください。

これらのメソッドがこのような単純なテストに失敗した場合は奇妙に思われるので、これに対する解決策があることを本当に望んでいます。

編集

Oracle 11gを使用しています。マッピングは、CastleWindsorを介してNHibernateファシリティに登録されたFluentNHibernateを使用して行われます。私が書いたように、奇妙なことに、クエリはQueryOver <> APIで完全に機能しますが、LINQでは機能しません。

4

2 に答える 2

11

NHibernate Facility 2.0RC(および以前のバージョン)と一緒に使用されるNHibernate 3.1.0.4000のLINQ拡張メソッドの現在の実装に問題があります(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>ます。

それが私と同じ状況の誰かに役立つことを願っています。

于 2011-04-06T08:44:25.580 に答える
0

私は次を見つけました:http://groups.google.com/group/castle-project-users/browse_thread/thread/5efc9f3b7b5d6a08

どうやら、NHibernateファシリティとNHibernate3.1.0.4000の現在のバージョンに問題があります。

私はただ修正を待つ必要があると思います:)

于 2011-04-05T21:00:12.460 に答える