0

ここで入手可能な Ayende の NHibernate Linq バージョン 2.1.2 を使用しており、NHProf を使用してこのメ​​ソッドを使用するクエリを検査する場合:

public IQueryable<T> GetAll()
{
    return Session.Linq<T>();
}

暗黙のトランザクションを使用しているという警告が表示されます。問題は、これをリポジトリで使用してデータベース セッションを抽象化していることですが、必要な Linq クエリを実行できるように IQueryable を返す柔軟性が必要です。を公​​開せずにトランザクションで明示的にラップする方法はありますSession.Linq<T>()か、またはこの場合は警告を無視する必要がありますか?

もう少し背景。私は次のような方法を使用しています:

var repo = new Repository();
var animals = repo.GetAll<Animal>().Where(x => x.Size > 100);
NoahsArk.LargeAnimals.AddRange(animals);
4

3 に答える 3

3

NHProfのメッセージは、実際にはリポジトリの実装とは関係ありません。トランザクションの外部でクエリを実行していることを指摘しているだけであり、これが問題の原因となる可能性があります。

Ayendeはブログ投稿でこれを説明しています:NH Prof Alerts:暗黙のトランザクションの使用は推奨されていません

アプリケーションの上位レベルからトランザクションを管理する必要があります。リポジトリを使用しながらこれを行うにはいくつかの方法があります。unhaddinsを見てください

于 2009-12-20T18:23:07.420 に答える
1

私は非常に簡単に解決した非常によく似た問題を抱えていました。

Linq メソッドによって返されたリポジトリ内に LinqClass を作成しました

public virtual LinqClass Linq()
{
    return new LinqClass(Session, LinqSource());
}

public class LinqClass : IDisposable
{
    public LinqClass(ISession session, IQueryable<T> linqSource)
    {
        _linq = linqSource;
        _transaction = session.BeginTransaction();
    }
    private readonly IQueryable<T> _linq;
    private readonly ITransaction _transaction;

    public IQueryable<T> Linq
    {
        get { return _linq; }
    }

    public void  Dispose()
    {
         _transaction.Commit();
    }
}

次に、linq ステートメントを using ブロックにラップすることができます

    using (var linq = Linq())
    {
        var versions = from t in linq.Linq
                       where t.BaseName == BaseName
                       orderby t.Version descending
                       select t.Version;

        return versions.Take(1).SingleOrDefault();
    }

途中からデータを返しても、トランザクションのコミットは呼び出されます。暗黙のトランザクションはもうありません。明らかに、この例は NHibernate 用ですが、他のものでも同様に機能するはずです。

于 2011-07-19T11:33:34.750 に答える
0

この警告は無視できると確信しています。

NHProfでトランザクションを確認できますか?

http://groups.google.com/group/nhprof/browse_thread/thread/fbc97d3286ad783b

于 2009-12-20T14:33:40.997 に答える