我正在使用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);
答案 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