7

내 ASP.NET MVC 응용 프로그램에서 도메인 모델을 뷰 모델에서 분리했습니다.
필자는 viewmodel 개체에서 엔티티를 변환하므로 필요한 데이터만으로 내 뷰를 "피드"할 수 있습니다 (이 목적으로 valueinjecter를 사용했습니다).
저장 프로세스 중에 내 컨트롤러가 viewmodel 개체를 가져 와서 도메인 모델 엔터티로 변환하고 SaveOrUpdate로 유지하려고 시도합니다. 기존 레코드를 업데이트하려고하면 Nhibernate가 해당 레코드를 새 개체로 간주하고 내 엔터티에 올바른 ID가 있어도 INSERT를 수행합니다.
필자는 모든 필드를 다시 매핑하지 않기 때문에 엔티티를로드 (로드 /로드)하지 않았습니다.
내가 잘못하고있는 것이 있습니까? 이를 달성하는 가장 좋은 방법은 무엇입니까?Nhibernate에서 SaveOrUpdate하기 전에 엔티티를로드/가져와야합니까?

***** - UPDATE - ***

내 컨트롤러, 사용자 (뷰 모델)를 수신을 확인하고 엔티티와 같은 서비스 레이어를 통해 저장하려고

:

public ActionResult Edit(Guid id, Models.User User) 
{ 
... 
var user = new Domain.User(); 
user.InjectFrom(User); 
user.SetId(id); 

user = this._SecurityService.SaveUser(user); 

} 

public Domain.User SaveUser(Domain.User User) 
     { 
      bool Result = false; 

      if (this._ValidationEngine.IsValid(User)) 
      { 
       using (_UnitOfWork) 
       { 
        if (User.Code != Guid.Empty) 
        { 
         var user = this._UserRepository.Load(User.Code); 
         user.InjectFrom(User); 
         User = this._UserRepository.Update(user); 
        } 
        else { 
         User = this._UserRepository.Save(User); 
        } 
        Result = _UnitOfWork.Commit(); 
       } 
      } 
      return (User); 
     } 

내가 너무 여러 번 내 뷰 모델/개체를 변환 할 필요가 있다는 사실에 대해 우려를 가지고있다 :이 서비스입니다. 이제 새로운 사용자를 저장하려고하면 다음 메시지가 나타납니다. 행이 다른 트랜잭션에 의해 업데이트되거나 삭제되었습니다 (또는 저장되지 않은 값 매핑이 잘못되었습니다)
아마 이것은 대린이 말한 것과 관련이 있습니다.
내가하려는 일을하는 더 좋은 방법이 있습니까? 내가 오류 것으로 나타났습니다

UPDATE "행이 갱신 또는 삭제 ..."은 내 매핑에 대해 정의 된 버전을 가지고 있다는 사실에 기인한다. 내가 이해할 수있는 것은 내가 업데이트하고자하는 엔티티와 일치하는 Id버전이 필요하다는 것입니다.
다른 사람들이 DDD + ASP.NET MVC + NHibernate로 이러한 작업을 수행하는 방법을 알고 싶습니다. ???

솔루션

내 모든 엔티티 버전이 정의 (미안 말을 잊었) :

<version name="Version" type="System.Int32" unsaved-value="0"> 
    <column name="Version" not-null="true" /> 
</version> 

Ayende이 here을 설명하고있는 바와 같이, NHibernate에이 같은 쿼리 내 개체를 업데이트하려고 :

UPDATE Table SET field1 = 'bla', Version = (y+1) WHERE id = x AND Version = y 

여기서 y는 내 엔티티의 버전이어야합니다. 내 엔티티에 버전을 채우지 않았으므로 StaleObjectException 예외가 발생합니다.
내 viewmodel에 버전 필드를 추가했습니다. 나는 이드와 함께 내보기의 숨겨진 필드에 저장합니다.
이제 내 컨트롤러가 ID와 버전으로 뷰 모델을 수신합니다. 는 내 도메인 엔티티에 이러한 필드를 주입하고 (내 엔티티를 다시로드하지 않음) 저장소에 저장하자 : 나는 StaleObjectException 예외가 발생하는 경우

User = this._UserRepository.Update(user); 

그것은 다른 사람이 DB 행을 업데이트했습니다 것을 의미한다 나는 사용자에게 약간의 피드백을 줄 것이다.

+0

엔티티를 로딩하고 다시 매핑 한 후 (이 방법이 필요 없다는 것을 알고 있습니다.)이 방법으로 작동하는지 알려면 – Omu

+0

문제가있는 것 같습니다. "매핑"에 정의 된 <버전 이름 = "버전"유형 = "System.Int32 저장되지 않은 값 ="0 "> LeftyX

답변

0

이미 ID가 있으므로 업데이트임을 알고 있으므로 SaveOrUpdate 대신 session.Update을 사용하십시오.

+0

엔티티를 저장하려고하면이 메시지가 표시됩니다. 같은 식별자 값을 가진 다른 객체가 이미 세션과 연결되어 있습니다. caedb8a4-abce-4c6f-b171-9e7200cc7a37, entity : BpReminders.Domain.User – LeftyX

+0

개체가 이미로드되었음을 의미합니다. 왜 이미로드 된 객체를 업데이트하지 않습니까? –

+0

죄송합니다. 실수였습니다. 내가 지금하고있는 일은 저장소에서 엔티티를 로딩하고 그것을 컨트롤러에서 얻은 엔티티와 병합하는 것이다. 삽입하려고하면 "행이 업데이트되었거나 다른 트랜잭션에 의해 삭제되었습니다 (또는 저장되지 않은 값 매핑이 잘못되었습니다)"오류가 계속 발생합니다. 나는 원래의 질문을 더 많은 정보로 업데이트 할 것이다. – LeftyX

4

SaveOrUpdate이 예상대로 작동하려면 <id> 매핑에 unsaved-value 특성을 명시 적으로 지정해야합니다.

<id unsaved-value="0" ... 

을 다음 0 다른 값으로 할당 된 Id 속성을 가진 모델에 SaveOrUpdate 전화를 발행하고 그것은 UPDATE 대신 INSERT에가는 : 그래서 예를 들어, 당신은 할 것이다. 질문에 대답하려면 아니요, UPDATE 전에 SELECT을 수동으로 발행 할 필요가 없습니다. SaveOrUpdate이 작업을 수행해야합니다.

+0

대담하게 감사합니다. 내 ID가 Guid 유형 인 경우 비어있는 Guid (00000000-0000-0000-0000-000000000000)를 사용해야합니다. – LeftyX

+0

@vandalo, 이것을 시도해보십시오. 'unsaved-value = "00000000-0000-0000-0000-000000000000"'(테스트되지 않음) –

+0

어쨌든, 당신은 무엇을하겠습니까? DB에서 엔티티를로드하고 각 엔티티를 새 엔티티로 채워야합니까? 캘리포니아에 se 업데이트를 시도하고 있습니까? 모범 사례가 있습니까? 도와 줘서 고마워. – LeftyX

관련 문제