2012-02-02 5 views
2

FluentNhibernate;매핑 nhibernate 부모/자식 관계 '다른'방법 라운드

나는 단순 해 보이는 개체 모델 유지하는 것을 시도하고있다 :

public class Product 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public Config Config { get; set; } 
} 

public class Config 
{ 
    public int ConfigId { get; set; } 
    public int ProductId { get; set; } 
    public string ConfigField1 { get; set; } 
    public string ConfigField2 { get; set; } 
} 

과 같은 데이터베이스가 같습니다 상자 유창 - NHibernate에 부족

CREATE TABLE [dbo].[Products](
[ProductId] [int] IDENTITY(1,1) NOT NULL, 
[Name] [varchar](50) NULL 
) 

CREATE TABLE [dbo].[Config](
[ConfigId] [int] IDENTITY(1,1) NOT NULL, 
[ProductId] [int] NOT NULL, 
[ConfigField1] [varchar](50) NULL, 
[ConfigField2] [varchar](50) NULL 
) ON [PRIMARY] 

시도 할 것이다 (문법적으로 정확하지 않음)

INSERT INTO 제품 (이름, Config_ 다음 Products 테이블 예에 외래 키로이지도 id) VALUES (?,?);

필자는 매핑이 제품을 먼저 삽입하고 구성 테이블에 ProductId이 삽입되고 Config 테이블에 삽입되기를 바라고 있습니다.

나는 내 머리를 꺼내어 과 this과 같은 링크를 읽었지만 여전히 원하는대로 할 수는 없습니다. 기존 데이터와 코드으로 작업 중이므로 데이터베이스 테이블 정의 또는 도메인 개체를 변경하지 않을 것입니다. 도메인 모델 디자인에 대한 토론을 피할 수 있다면이 예제가 그리는 것보다 더 많은 일이있을 것입니다.

public class ProductOverrides : IAutoMappingOverride<Product> 
{ 
    public void Override(AutoMapping<Product> mapping) 
    { 
     mapping.Id(x => x.Id).Column("ProductId");    
     mapping.Table("Products"); 
    } 
} 

public class ConfigOverrides : IAutoMappingOverride<Config> 
{ 
    public void Override(AutoMapping<Config> mapping) 
    { 
     mapping.Id(x => x.ConfigId); 
    } 
} 
+0

시도해 보셨습니까? http://brunoreis.com/tech/fluent-nhibernate-hasone-how-implement-one-to-one-relationship/ –

+0

그게 어떻게 도움이되는지 설명해 주시겠습니까? 'Config'는 자체 기본 키'ConfigId'를 가지고 있지만'ProductId' – wal

답변

4

당신은 하나에 같은 일대일 관계를 매핑하는 데 노력하고있다 :이 프로젝트 here

내 현재 유창 매핑

는 (데이터베이스가 존재하는 것으로 간주)의 스파이크로 링크를 - 여러면을 두 번 매핑 할지도 모를 매핑. 그것은 작동하지 않습니다. NHibernate는 one-to-one의 정의가 엄격하며 양쪽에 동일한 기본 키가 있어야하므로 작동하지 않습니다.

나는 butted heads with this before을 가지고 있었고 가장 좋은 해결 방법은 표준 일대 다수로 모델링하는 것이지만 액세스를 캡슐화하여 컬렉션의 항목 하나만 허용하는 것이 었습니다. 귀하의 경우 나는 제품이 한쪽면이고 많은면을 구성 할 것이라고 추측합니다. 구성이 다른 곳에서 사용되지만 당신은 그것의 ID로 ConfigId을 무시할 수 있다면

+0

을 통해 제품에 다시 링크되어야하므로, ListConfigs 속성을 추가해야 할 필요가 있기 때문에 필요한 것은 1 대 1 관계입니다 'Product' 클래스에요? – wal

+0

아니요, 컬렉션 (목록 대신 매핑 설정하는 것이 좋습니다)을 개인 회원으로 추가하고 액세스 전략을 사용하여 매핑하십시오. 그런 다음 컬렉션의 하나의 Config 만 허용하는 공용 Config 속성을 통해 컬렉션을 제어합니다. 연결된 질문을 참조하십시오. –

+0

그래, 그게 이상적이 아닌가 먼저 nhibernate하시기 바랍니다 내 도메인 개체를 변경하지 않도록 노력하고있어 좋아. 두 번째로 나는 전선을 가로 질러 그것을 보내고,'Set'은 내가 가질 수없는 nhibernate 클래스라고 가정하고 있습니다. – wal

2

는 잘 모르겠어요

public class Config 
{ 
    public int Id { get; set; } 
    public Product Product { get; set; } 
    public string ConfigField1 { get; set; } 
    public string ConfigField2 { get; set; } 
} 

public class ProductMap : ClassMap<Product> 
{ 
    public class ProductMap() 
    { 
     HasOne(p => p.Config); 
    } 
} 

public class ConfigMap : ClassMap<Config> 
{ 
    public class ConfigMap() 
    { 
     Id(c => c.Id, "ProductId").GeneratedBy.Foreign("Product"); 

     References(c => c.Product, "ProductId"); 
     Map(c => ...); 
    } 
} 
+0

항상 두 답변에 대해 감사드립니다. 이 두가지 해결책의 문제점은 Product가 다른 키를 사용하는 것을 배제한 'component'로서 * 다른 * 클래스에 의해 사용된다는 것입니다 ('Config'가 클래스 '제품'이외의. 나는 가장 쉬운 것은 제품 테이블에'ConfigId'를 저장하기 위해 데이터베이스를 재정의하는 것이라고 생각하고 있습니다. – wal

+0

물론 가능한 경우 db를 변경하는 것이 가장 쉽습니다.하지만 다른 클래스에서도 Config를 매핑 할 수 있습니다. 다른 전화 번호를 가진 구성 요소로 – Firo

+0

ID (c => c.Id, "ProductId"). 다음과 같이이 라인에 대해 무엇을 할 것인가 : GeneratedBy.Foreign ("Product"); 다른 클래스는'Product' Config가 다른 클래스에 의해 ' – wal

1
또 다른 아이디어는 가입

public class ProductMap : ClassMap<Product> 
{ 
    public class ProductMap() 
    { 
     Join("Config", join => 
     { 
      join.KeyColumn("ProductId"); 
      join.Component(p => p.Config, c => 
      { 
       c.Map(...); 
      }); 
     } 
    } 
} 

단점 구성 요소로 매핑하는 것이다

은 당신이 할 수 있다는 것입니다 쿼리를 직접 구성하지 않고 제품을 통해 쿼리해야합니다.