2017-12-13 26 views
1

나는 계층화 된 아키텍처 패턴을 따르려고하는 다소 큰 응용 프로그램을 개발 중이다. DBAL에서는 유창하게 구성된 NHibernate를 사용합니다. 데이터베이스 오브젝트는 가끔이 같은 연결을 가지고 다음과 같이NHibernate를 사용하여 엔티티의 관련 객체를 지속하는 전략

public class HeaderDbo 
{ 
    public HeaderDbo() 
    { 
     Details = new List<DetailDbo>(); 
    } 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
    public virtual IList<DetailDbo> Details { get; set; } 
} 

public class DetailDbo 
{ 
    public virtual int Id { get; set; } 
    public virtual string DetailName { get; set; } 
    public virtual HeaderDbo Header { get; set; } 
    public virtual RelevantObjectDbo RelevantObject { get; set; } 
} 

public class RelevantObjectDbo 
{ 
    public virtual int Id { get; set; } 
    public virtual string RelevantText { get; set; } 
} 

매핑은 다음과 같습니다

public class HeaderDboMap : ClassMap<HeaderDbo> 
{ 
    public HeaderDboMap() 
    { 
     Table("Header"); 
     Id(x => x.Id).Column("Id"); 
     Map(x => x.Name); 
     HasMany(x => x.Details) 
      .Inverse() 
      .Cascade.All(); 
    } 
} 

public class DetailDboMap : ClassMap<DetailDbo> 
{ 
    public DetailDboMap() 
    { 
     Id(x => x.Id).Column("Id"); 
     Table("Detail"); 
     Map(x => x.DetailName); 
     References(x => x.Header).Column("HeaderId"); 
     References(x => x.RelevantObject).Column("RelevantObjectId") 
      .Cascade.SaveUpdate(); //?? 
    } 
} 

public class RelevantObjectDboMap : ClassMap<RelevantObjectDbo> 
{ 
    public RelevantObjectDboMap() 
    { 
     Id(x => x.Id).Column("Id"); 
     Table("RelevantObject"); 
     Map(x => x.RelevantText); 
    } 
} 

을 이제 DBOs 반드시 데이터베이스 구조를 반영하지 않습니다 어떤 매핑되는 응용 프로그램 도메인의 개체가있는 원 - 1 대 1. 예를 들어, Header는 헤더를 유지할 수 있지만, Detail은 DetailDbo 및 RelevantObjectDbo의 일부로부터 형성됩니다. 그런 다음 응용 프로그램이 엔티티에 대해 수행합니다. Detail의 일부 변환이 이제는 지속되어야합니다.

디테일 테이블에 들어가야하는 디테일 엔티티의 부분에만 영향을주고 어떤 식 으로든 RelevantObject 테이블에는 영향을 미치지 않는다고 가정합니다. 모델에 대해 생각하는 것은 잘못된 방법 일 수 있지만 지속성이 작동하는 방식에 대해 실용적이어야합니다. 그래서, 나는 NHibernate가 RelevantObject 테이블에서 아무 것도 만지지 않고 Detail 테이블 만 업데이트하도록하고 싶습니다. 이것은 정확히 질문입니다. 실제로 : 어떻게 성취합니까?

실제로 DB 모델은 훨씬 더 크고 복잡하며 응용 프로그램 논리도 마찬가지입니다. 데이터의 RelevantObject 부분을 전혀 다루지 않는 BL의 일부가있을 수 있으므로 DBO가 DB에서 완전히로드 되어도 모든 데이터가 앱 모델로 이동하는 것은 아닙니다. 그러나 데이터를 다시 데이터베이스에 보관하려면 DB 모델을 완전히 수화해야하며 항상 실용적이지는 않습니다. 그래서, 우리는 어떻게 NHibernate에게 RelevantObject를 "만지지 말라"고 지시 할 수 있습니까? 다시 말하면, dbo.Detail.RelevantObjectId를 업데이트하지 않습니까?

DetailDbo.RelevantObject 속성에 다른 케스케이드 옵션을 적용 해 보았습니다.하지만 null에 머물러 있다면 NHibernate는 항상 RelevantObjectId를 NULL로 설정하려고합니다. 나는 정당하다고 생각합니다.

모든 연관성을 통해 데이터베이스의 절반을로드하고 저장하지 않아도 BL의 "파트"와 관련된 데이터에 어떻게 변경을 쓸 수 있는지 이해할 수 없습니다.

감사합니다.

+0

DetailDbo.RelevantObject에서 캐스케이드를 없음으로 설정하고 올바른 ID가 설정된 "빈"개체를 속성으로 설정하면 업데이트가 원하는대로 수행됩니다 (예 : 참조 dbo). Detail.RelevantObjectId가 올바르게 설정되어 있고 dbo.RelevantObject가 수정되지 않았습니다. 그러나 이것은 너무 서투르다, 나는 생각한다 - 더 좋은 길은 없는가? –

+0

지금보고있는 전략 중 하나는 db의 저장 엔티티와 저장을 담당하는 저장소에서 저장소가 "원하는"정도까지 DBO를 읽은 다음 해당 개체를 엔티티에서 업데이트하고 저장하는 것입니다 뒤로. 그것은 또한 다소 서툴기는하지만, "무엇을 유지할 것인가"의 논리가 DBAL 내에 포함되어 있기 때문에 접근법을 좋아합니다. 이는 엔터티가 지속성 세부 사항을 불가지론해야하므로 적합합니다. 지금 경제적 인 방법으로 이것을 구현하려합니다 ... –

답변

0

어떻게 이러한 업데이트를 수행하고 있습니까? RelevantObject에서 아무것도 수정하지 않으면 NHibernate는 해당 테이블에 대한 업데이트를 전송하지 않습니다. 예를 들어 :

var header = session.Get<HeaderDbo>(1); 
header.Details.First().DetailName = "Whatever"; 
session.Flush(); 

는 업데이트가 RelevantObject 테이블에 발행되도록해서는 안된다.

+0

사실입니다. 그러나 문제는 때때로 DBO의 카피 본이 아닌 엔티티를 유지해야 할 때가 있다는 것입니다.예를 들어, HeaderDbo, DetailDbo, RelevantObjectDbo (데이터베이스 테이블의 반영) 대신 BusinessEntity 객체를 처리합니다. 그리고이 엔티티는 dbo.Header 및 dbo.Detail 테이블에 유지되어야합니다. 따라서 HeaderDbo 및 DetailDbo를 사용하여이 "저장"을 수행하는 것이 자연 스럽지만 BusinessEntity에 대한 정보가 부족하여 DBO의 전체 별자리를 다시 만들 수 없습니다. 충돌. –

+0

나는 완전히 따라갈 지 모르겠다. BusinessEntity에있는 정보에서 얻을 수있는 엔티티를 가져 와서 그 엔티티 만 업데이트 하시겠습니까? 일부 속성을 값으로 업데이트하면 이미 괜찮습니다. 이해할 수있는 상황에 대한보다 완벽한 예가 필요하다고 생각합니다. 어쨌든, 열 수준의 업데이트를 피하는 것이 도움이 될 경우, "DynamicUpdate();"를 사용할 수 있습니다. NH의 매핑에서 엔티티의 수정 된 열에 대해서만 업데이트를 발행하면됩니다. –

+0

합법적 인 (그리고 사용한?) 전략은 DBO를 데이터베이스에서로드하고 BusinessEntity에서 업데이트하는 것입니다 - 특정 비즈니스 운영에 필요한 방식? 이것은 내가 결국 한 일종의, 실제로 나는 솔루션을 좋아했습니다. 내가 더 나은 것을 놓치고 있는지 궁금해하고 있었다. –

관련 문제