NHibernate Linq使用隐式事务?

时间:2009-12-20 11:25:12

标签: nhibernate transactions linq-to-nhibernate nhprof

我正在使用Ayende的NHibernate Linq 2.1.2版,可用here,当我使用NHProf检查使用此方法的查询时:

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

它告诉我我正在使用隐式事务。问题是,我在存储库中使用它来抽象出数据库会话,但我仍然希望返回IQueryable的灵活性,以便我可以运行我想要的任何Linq查询。有没有办法明确地将Session.Linq<T>()包装在事务中而不暴露它,或者我应该在这种情况下忽略警告?

多一点背景。我正在使用这样的方法:

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

3 个答案:

答案 0 :(得分:3)

NHProf的消息实际上与您的存储库实现无关。它只是指出你在事务之外运行查询,这可能是问题的根源。

Ayende在博文中解释了这一点:NH Prof Alerts: Use of implicit transactions is discouraged

您应该在应用程序的更高级别管理您的交易。使用存储库时有几种方法可以执行此操作,请查看unhaddins

答案 1 :(得分: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 (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,但它应该适用于其他事情。

答案 2 :(得分:0)

我很确定你可以忽略这个警告。

你能看到NHProf的交易吗?

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