2010-07-23 3 views
0

다음 단원 테스트가 실패합니다. 검색 한 객체를 변경 한 다음 동일한 세션에서 미사용 변경 사항을 고려한 쿼리를 만듭니다. 그 물건을 만들었 어.NHibernate 질의는 데이터베이스에 아직 저장되지 않은 변경을 반환합니다.

어떻게 NHibernate가 커밋되지 않은 변경 사항을 무시하고 데이터베이스 만 쿼리 할 수 ​​있습니까?

[Test] 
public void Test() 
{ 
    // Arrange 
    Area area1 = new Area { Name = "Area 1" }; 
    Area area2 = new Area { Name = "Area 2" }; 
    using (ISession session = SessionFactory.OpenSession()) 
    { 
     using (var transaction = session.BeginTransaction()) 
     { 
      session.Save(area1); 
      session.Save(area2); 
      transaction.Commit(); 
     } 
    } 
    int resultCount; 

    // Act 
    using (ISession session = SessionFactory.OpenSession()) 
    { 
     Area existingArea; 
     using (var transaction = session.BeginTransaction()) 
     { 
      existingArea = session.Get<Area>(area1.ID); 
     } 

     existingArea.Name = area2.Name; 

     using (var transaction = session.BeginTransaction()) 
     { 
      resultCount = session.CreateCriteria<Area>().Add(Restrictions.Eq("Name", existingArea.Name)).List<Area>().Count; 
     } 
    } 

    // Assert 
    Assert.AreEqual(1, resultCount); 
} 

답변

4

내가 필요한 것을 발견했습니다 기본 FlushMode (FlushMode.Auto가) 쿼리하기 전에 데이터베이스에 때때로 플러시 변화가 부실 읽기 방지하기 때문에

session.FlushMode = FlushMode.Commit; 

문제는 발생했다. FlushMode.Commit으로 변경하면 내 필요에 맞는 커밋이 호출되었을 때만 데이터베이스에 변경 사항을 씁니다.

도움 주셔서 감사합니다.

+0

(+1) 감사합니다. 나는 그 사실을 알지 못했고 앞으로도 그것을 알게 될 것입니다. – gillyb

+0

btw - 어디서 읽었습니까? – gillyb

+0

'session'을 입력했습니다. Visual Studio에서 자동 완성 목록을 스크롤하여 눈에 띄는 것들을 찾습니다. FlushMode.Auto에 대한 도움말 텍스트 툴팁을 읽으면서 그것을 버렸습니다. – Matt

1

세션 내에서 변경 한 모든 내용은 세션 전체에서 유지됩니다. 따라서 세션 내에서 세션에서 이전에 변경된 데이터와 데이터베이스 스키마와 일치하는 데이터를 알 수있는 방법이 없습니다.

두 개의 다른 세션을 열어서이 문제를 해결할 수 있습니다. 그 중 하나에서 변경하지 마십시오, 그리고 당신은 항상 당신이 밖으로 시작했다 알 수 있습니다.

... 또는 내역 추적이 필요한 응용 프로그램의 특정 지점이있는 경우 추적하려는 특정 항목의 모든 변경 사항을 저장하는 일종의 내역 표를 만들 것입니다. 나는이 솔루션이 가장 좋을 것이라고 생각하지만, 다시 한번, 당신의 특정 요구가 무엇인지에 달려있다.

+0

답장을 보내 주셔서 감사합니다. ASP.NET 응용 프로그램에서 사용하고 요청 당 하나의 세션을 엽니 다. 코드 샘플을 참조하여 existingArea를 가져온 다음 폼 요소의 값을이 요소로 읽어들입니다. 그런 다음 다른 영역과 충돌하는 값으로 값을 변경하지 않도록 쿼리를 수행합니다 (이름은 고유해야 함). 다중 세션은 옵션이 아니며 히스토리를 추적 할 필요가 없습니다 (최소한이 맥락에서는 그렇지 않습니다). 세션에서 무엇이 변경되었는지는 특히 알 필요가 없습니다. 쿼리를 데이터베이스로 곧바로 보내야합니다. – Matt

+0

정확하게 이해했는지 확신 할 수는 없지만 새로운 영역 개체를 Clone 할 수는 있습니다. 그리고 나서 변경 사항을 적용 할 때 변경된 개체와 변경된 개체를 복제 전에 비교할 수 있습니다. IClonable과 IComparable을 Area 개체에 구현하면 코드 전체에서 매우 쉽게 수행 할 수 있습니다. – gillyb

관련 문제