2009-12-20 5 views
0
내가 Ayende의 NHibernate에 Linq에 버전 2.1.2을 사용하고

사용할 수 here, 나는이 방법을 사용하는 쿼리 검사 NHProf를 사용할 때 :NHibernate Linq는 암시 적 트랜잭션을 사용합니까?

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

답변

1

매우 간단하게 해결 한 비슷한 문제가있었습니다.

나는

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

난 다음 사용하여 블록에서

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

및 내 LINQ 문을 포장 할 수 내 Linq에 메소드에 의해 돌려 내 저장소 내에서 LinqClass을 만들어도 중간에서 데이터를 반환하는 경우 트랜잭션 커밋은 여전히 ​​호출됩니다. 암시 적 거래는 더 이상 발생하지 않습니다. 분명히이 예제는 NHibernate를위한 것이지만, 다른 것들과 비슷하게 작동해야한다.

+0

현명한 구현! –

+0

감사. 또한 효율성을 높이기 위해 단일 트랜잭션에서 데이터베이스에 대해 여러 명령문을 실행할 수 있습니다. 내 실제 구현은 트랜잭션 형식 매개 변수를 사용하여 트랜잭션 등방성 수준을보다 잘 제어 할 수 있다는 점에서 약간 더 복잡하며 NH에서 추상화하고 있습니다. –

3

은 NHProf의 메시지는 실제로 저장소 구현 관련이 없습니다. 문제의 원인이 될 수있는 트랜잭션 외부에서 쿼리를 실행하고 있음을 지적하는 것입니다.

Ayende은 블로그 게시물이 설명 : 당신은 당신의 응용 프로그램에서 더 높은 수준에서 거래를 관리해야 NH Prof Alerts: Use of implicit transactions is discouraged

. 저장소를 사용하는 중에 저장소를 사용하는 방법은 여러 가지가 있습니다. unhaddins