NHibernate Linq uses implicit transaction?
I'm using Ayende's NHibernate Linq version 2.1.2, available here, and when I use NHProf to inspect queries that use this method:
public IQueryable<T> GetAll()
{
return Session.Linq<T>();
}
It gives me the warning that I'm using an implicit transaction. Problem is, I'm using this in a repository to abstract out the database session, but I still want the flexibility of returning an IQueryable so I can run any Linq query I want. Is there a way to explicitly wrap the Session.Linq<T>()
in a transaction without exposing it, or should I开发者_如何学JAVA just ignore the warning in this case?
A little more background. I'm using the method like so:
var repo = new Repository();
var animals = repo.GetAll<Animal>().Where(x => x.Size > 100);
NoahsArk.LargeAnimals.AddRange(animals);
NHProf's message is actually not related to your repository implementation. It's just pointing out that you are running your query outside a transaction, which can be a source of problems.
Ayende explains this in a blog post: NH Prof Alerts: Use of implicit transactions is discouraged
You should manage your transactions from a higher level in your application. There are several ways to do this while using repositories, have a look at unhaddins
I had a very similar problem which I solved quite simply.
I created a LinqClass within my repository returned by my Linq method
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();
}
}
I could then wrap my linq statements up in a using block
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();
}
and even if returning data from the middle of it, the transaction commit is still called. No more implicit transactions. Obviously this example is for NHibernate, but it should work similarly for other things.
I'm pretty sure you can ingnore this warning.
Can you see the transaction in NHProf?
http://groups.google.com/group/nhprof/browse_thread/thread/fbc97d3286ad783b
精彩评论