문제

Rhino Commons UnitoFwork (ASP-MVC의 경우 UnitofWorkpplication)를 사용할 때 Rhino Repository STATIC 클래스를 사용하여 다음과 같은 엔티티를 저장하는 것을 좋아합니다.

Repository<Car>.Save(new Car(Id = 1));

그런 다음 전화 직후에 엔티티를 꺼낼 수 있음을 알았습니다.

Car car = Repository<Car>.Get(1);

이것은 잘 작동합니다. 그러나 rhino unitofwork에서 nhibernate linq 제공 업체를 사용할 때 다음과 같이 사용합니다.

var allCars = (from rep in UnitOfWork.CurrentSession.Linq<Car>()
               select rep).ToList();

빈 목록을 얻습니다. 이렇게 차를 꺼내기 전에 itorofwork.current.flush ()를 호출 해야하는 것 같습니다. 무대 뒤에서 두 검색 방법이 동일한 세션 / 작업 단위를 쿼리하고 있다고 생각하는 이유를 이해하지 못합니다. 이것은 데이터베이스에 저장 한 후 initofwork.current.flush ()를 호출해야한다는 것을 의미합니까? nhibernate가 스스로 플러시 할 때 해결할 수 없어야합니까? 아니면 내가 뭔가 오해하고 있습니까?

도움이 되었습니까?

해결책

좋아, 저장소에 대한 호출은 세션 캐시를 사용할 수 있지만 캐시에서 저장된 자동차를 '볼 수있다'는 것 같습니다.

Car car = Repository<Car>.Get(1); // This works because it uses the same session

LINQ 쿼리는 세션 캐시를 사용하지 않습니다.

var allCars = (from rep in UnitOfWork.CurrentSession.Linq<Car>()               
select rep).ToList(); // Does not work, even if it is in the same code block and even though it uses the same session

따라서 모범 사례는 모든 데이터베이스 변경 (저장, 업데이트, 삭제, 삽입)을 따라야합니다.

UnitOfWork.Session.Flush(), 

또는 a로 싸서 :

With.Transaction(delegate{
   // code here
})

또는 [트랜잭션]으로 방법을 장식하고 ATM을 사용하십시오. 이를 통해 후속 LINQ 쿼리가 최신 데이터를 검토 할 것입니다.

다른 팁

저장소를 호출하면 저장소가 보유한 세션에 해당 객체를 추적하고 다음 플러시에서 데이터베이스의 변경 사항을 동기화하도록 알립니다. 세션을 플러시 할 때까지 데이터베이스가 변경되지 않습니다. 객체는 세션 캐시의 일부가되므로 get (1)에 의해 반환됩니다.

컬렉션을 채우기 위해 쿼리를 실행하면 세션은 이미 해당 결과를 캐시하지 않는 한 결과를 얻기 위해 데이터베이스를 쿼리합니다. 아직 데이터베이스를 업데이트하지 않았으므로 세션에 추가 한 차량은 결과 세트의 일부가 아닙니다. (<-아마도 잘못) 문서를 올바르게 읽는 경우 쿼리 결과 및 Save () ED 엔티티가 세션 (1 단계) 캐시에 추가되어야합니다. 그것이 반드시 그 의미는 아닙니다 querystatement.List() DB 결과를 추가 한 후 캐시를 쿼리합니다 ... 나는 무슨 일이 일어나고 있는지 정확히 머리를 감싸는 데 어려움을 겪고 있습니다.

제쳐두고, 나는 당신이 세션을 자동 플러시로 설정할 수 있다고 생각하지만 문서를 확인해야합니다.

업데이트:

나는 여기서 무슨 일이 일어나고 있는지 볼 수 있다고 생각합니다. 기본 세션 FlushMode ~이다 Auto 그러나 코뿔소의 UnitOfWork.Start() a와 세션을 만듭니다 FlushMode 로 설정 Commit, 이는 명시 적으로 전화하지 않으면 세션이 자동 플러시되지 않음을 의미합니다. Flush() 또는 거래를 저 지르십시오. a FlushModeAuto, nhibernate는 쿼리하기 전에 세션을 플러시하여 오래된 데이터가 반환되는 것을 방지합니다. 내가 옳다면 DB 트랜잭션은 다음과 같습니다.

SELECT * FROM Car

INSERT INTO Car (...) VALUES (...)

자동 플러시가 내가 읽은 문서/블로그에서 약간 모호한 것처럼 보일 때 ... 가장 일반적인 대답은 FlushMode = Auto 보장하지만 "때때로"플러시됩니다 Session.Find 오래된 데이터를 반환하지 않습니다. NHibernate LINQ는 실제로 기준 쿼리 만 생성하기 때문에 자동 플러시를 트리거하지 않을 수 있습니다 (아마도 지금 고정되었을 수도 있습니다 ... 알기가 어렵습니다).

따라서 귀하의 경우 저장 후에 즉시 저장 결과를 검색하고 싶기 때문에 저장 후 플러시하고 싶을 것 같습니다. 엔티티 만 업데이트 한 작은 작업 단위에서는 단일 Commit ()가 괜찮을 것입니다. 아마도 UnitOfWork.CurrentSession.FlushMode = FlushMode.Auto; 트릭을 수행하지만 UOW 공장이 명시 적으로 커밋 할 모드를 명시 적으로 설정한다는 사실은 UOW 경계에 대해 실제로 생각하도록 격려하는 것 같습니다.

Stuart Childs 덕분에 문제가 Nhibernate LINQ 제공 업체와 함께있을 수 있다고 생각합니다. 나는 그것이 무대 뒤에서 무엇을하는지 잘 모르겠지만 다른 세션을 사용할 수 있습니다. 그렇다면 LINQ 쿼리가 '보기'전에 저장을 플러시해야한다는 것이 합리적입니다. 소스 코드를 살펴볼 시간이지만 그것을 이해하려고 내 머리를 녹일 것이라고 들었습니다!

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top