2

기존 데이터베이스 (실제로 IBM i의 DB2)에 액세스하고 Fluent NHibernate에서 다음 (단순) 구조에 대한 매핑에 문제가 있습니다. 나는 인공적인 예를 만들어야 만 했으므로 어떤 죄목도 용서할 수 있습니다.DB2 Fluent HasMany 매핑에서 중복 레코드를 매핑하는 NHibernate

작업 ...

public class Job 
{ 
    public virtual string JobCode { get; set; } 

    public virtual string Owner{ get; set; } 

    public virtual IList<Deliverable> Deliverables { get; set; } 

    public Job() 
    { 
     Deliverables = new List<Deliverable>(); 
    } 
} 

산출물 ..

public class Deliverable 
{ 
    public virtual string JobCode { get; set; } 

    public virtual int Package { get; set; } 

    public virtual string Owner { get; set; } 

    public virtual string Reference { get; set; } 

    public virtual Job Job { get; set; } 
} 

나는 다음과 같이 작업과 산출물 사이에 'hasMany의'관계를 매핑하는 것을 시도하고있다 ..

public class JobMap : ClassMap<Job> 
{ 
    public JobMap() 
    { 
     Table("JOB"); 

     Id(x => x.JobCode).Column("CODE"); 

     Map(x => x.Owner).Column("WHODO"); 

     HasMany(x => x.Deliverables) 
      .KeyColumn("CODE"); 
    } 
} 

public class DeliverableMap : ClassMap<Deliverable> 
{ 
    public DeliverableMap() 
    { 
     Table("DELIVERABLE"); 

     Id(x => x.JobCode).Column("CODE"); 

     Map(x => x.Reference).Column("UNQREF"); 

     Map(x => x.Owner).Column("WHODO"); 

     References(x => x.Job) 
      .Column("CODE") ; 
    } 
} 

이것은 작동하는 것처럼 보입니다. 생성 된 SQL을 가져 와서 직접 실행하면 올바른 결과가 반환됩니다 (이 사례 11 기록, 모든 고유). 그러나 다음을 수행 할 때 산출물 목록에는 모두 11 개의 항목이 있습니다.

IList의 검색 결과 = 세션 .CreateCriteria (대해서 typeof (작업)) .Add (Expression.Eq ("번호", "206171")) .List();

foreach (var job in results) 
{ 
    Console.WriteLine("job.JobCode" + job.JobCode); 
    Console.WriteLine("job.Owner" + job.Owner); 

    foreach (var deliverable in job.Deliverables) 
    { 

    **// These are all identical!** 

    Console.WriteLine(deliverable.Reference); 
    Console.WriteLine("deliverable.Owner" + deliverable.Owner); 
    Console.WriteLine(deliverable.JobNumber); 
    Console.WriteLine(deliverable.DeliverableTyoe); 
    Console.WriteLine(deliverable.Description); 
    } 
} 

그래서 매핑이 잘못 되었나요? 아니면 내가 사용하고있는 방식으로 뭔가가 있습니까?

미리 감사드립니다. 나는 하루 종일 이것을보고있었습니다. (우리의 경우에 DelivarableJob)

대일 관계

답변

2

나는 그것을 고쳐 놓은 것 같습니다. 또한 다음과 같이 작업 매핑을 변경 내가 전달 가능한 클래스 다음

public override bool Equals(object obj) 
{ 
    if (obj == null) 
    return false; 

    var t = obj as Deliverable; 
    if (t == null) 
    return false; 

    if (JobCode == t.JobCode && Reference == t.Reference) 
    return true; 

    return false; 
} 

    public override int GetHashCode() 
    { 
    return (JobCode + "|" + Reference).GetHashCode(); 
    } 

과에 다음을 우선해야한다고 산출물 매핑

CompositeId() 
    .KeyProperty(x => x.JobCode, "CODE") 
    .KeyProperty(x => x.Reference, "UNQREF"); 

이 의미에 CompositeID을 추가

HasMany(x => x.Deliverables) 
    .KeyColumn("Codex") 
    .Inverse() 
    .Cascade.All(); 

이 중 어떤 것이 상황을 수정했는지 확신 할 수 없습니다 (나는 .Inverse()이 작업 맵핑에있는 것으로 의심됩니다.)

생성 된 SQL이 이제 어떻게 생겼는지는 모르겠지만 답변은 정확합니다.

+0

예, 의미가 있습니다. 앞에서 말했듯이 ID로 매핑되고 referenceId로 매핑 된 CODE만으로는 충분하지 않습니다. 실제 고유 ID가 누락되어 문제가 발생했습니다. 좋은 당신이 그것을 당신을 위해 일하게하십시오. Enjoy NHiberante;) –

+0

도움을 주셔서 감사합니다. 그것은 모두 감각을 만들기 시작합니다 – Mmarquee

+0

위대한;) 정말 대단한;) –

1

는, 관계 자체는 정확히 하나 DB 컬럼으로 표현된다. 하위 테이블 (Deliverable)에는 ID (코드)의 참조 열이 있어야합니다.

그래서 매핑에 필요한 것은 작업에 대한 관계가 포함 된 Delivarable 테이블의 열입니다. JobCode 열입니다.

(가 위의 어떤에서 예입니다 확실하지 않은 경우) 그리고이 양쪽에서 사용할 수 있어야합니다

Delivarable :

public DeliverableMap() 
{ 
    ... 
    // References(x => x.Deliverable) ... I guess it is typo in the question snippet 
    References(x => x.Job) 
     .Column("JobCode") ; // column of table Deliverable 
} 

작업 :

public JobMap() 
{ 
    ... 
    HasMany(x => x.Deliverables) 
     .KeyColumn("JobCode"); // column of table Deliverable 
} 

다른 단어, 이 매핑의 두 열 이름은 모두 실제로 열의 이름입니다. 둘 다 하위 (Deliverable) 테이블의 열에 매핑됩니다. EXTENDED

: 질문

Deliverable 오브젝트 매핑 변화를 기반으로 해당 ID (열 CODE) Job (열 CODE)의 참조와 동일하게 가진다. 이것은 이상하게 보입니다.

또한 JOB 컬렉션의 모든 산출물 항목이 과 같으며 (동일 함)이라는 사실을 설명합니다. 고유 산출물 (CODE로 정의 됨)은 하나 일 수 있습니다.이 시나리오의 작업은 고유 코드 열에 의해 참조되므로 전달 항목을 하나 이상 가질 수 없습니다. 일대일 시나리오 인 것 같습니다.

더 많은 이유는입니다. 같은은 판단하기가 어렵습니다. 사용중인 쿼리를 보는 것이 좋습니다.

하지만 실제로 열 매핑을 두 번 확인할 것입니다. "JobCODE"라는 열의 Job에 대한 참조가 있어야합니다. 더 많은 Delivrables가 관련되도록 지원해야합니다 ...

+0

감사합니다. - 원래 질문에서 오류를 수정했습니다. 내 코드는 기본적으로 위에서 제시 한 코드입니다. 생성 된 SQL은 로컬 컴퓨터에서 복사되어 실행될 때 필요한 결과를 산출하지만 내 코드에서 생성 된 산출물 모음에는 올바른 수의 결과가 있지만 내적 결과가 있습니다. – Mmarquee

+0

나는 나의 대답을 확장한다. 내게 정말로 싫증이 나는 것은 ID 및 작업 참조로 "코드"열입니다. –

+0

실제 파일에는 필드에 사용할 필드 이름이 동일합니다. 전달할 파일에는 '복합'키가 있습니다. Job (1) -> Deliverable (1) -> Deliverable (1) -> Deliverable (1) -> Deliverable (1) (3) Job (1) -> 배달 가능 (2) (1) 등 (서식에 대해 미안) – Mmarquee

관련 문제