3

다른 클래스를 매핑하는 데 CompositeId를 사용하는 방법을 알아 내려고하고 있습니다. C#에서Fluent NHibernate compositeid가 매핑 된 클래스

TestParent: 
    TestParentId (PK) 
    FavoriteColor 

TestChild: 
    TestParentId (PK) 
    ChildName (PK) 
    Age 

클래스 :

표 : 여기에 테스트 케이스의

public class TestParent 
{ 
    public TestParent() 
    { 
     TestChildList = new List<TestChild>(); 
    } 

    public virtual int TestParentId { get; set; } 
    public virtual string FavoriteColor { get; set; } 
    public virtual IList<TestChild> TestChildList { get; set; } 
} 

public class TestChild 
{ 
    public virtual TestParent Parent { get; set; } 
    public virtual string ChildName { get; set; } 
    public virtual int Age { get; set; } 

    public override int GetHashCode() 
    { 
     return Parent.GetHashCode()^ChildName.GetHashCode(); 
    } 

    public override bool Equals(object obj) 
    { 
     if (obj is TestChild) 
     { 
      var toCompare = obj as TestChild; 
      return this.GetHashCode() != toCompare.GetHashCode(); 
     } 
     return false; 
    } 
} 

유창 NHibernate에지도 :

public class TestParentMap : ClassMap<TestParent> 
{ 
    public TestParentMap() 
    { 
     Table("TestParent"); 
     Id(x => x.TestParentId).Column("TestParentId").GeneratedBy.Native(); 
     Map(x => x.FavoriteColor); 

     HasMany(x => x.TestChildList).KeyColumn("TestParentId").Inverse().Cascade.None(); 
    } 
} 

public class TestChildMap : ClassMap<TestChild> 
{ 
    public TestChildMap() 
    { 
     Table("TestChild"); 
     CompositeId() 
      .KeyProperty(x => x.ChildName, "ChildName") 
      .KeyReference(x => x.Parent, "TestParentId"); 

     Map(x => x.Age); 
     References(x => x.Parent, "TestParentId"); /** breaks insert **/ 
    } 
} 

나는 새를 추가하려고 이 오류가 발생합니다.

System.ArgumentOutOfRangeException : Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index

이 오류는 TestParentId 열이 CompositeId 및 References 호출에 매핑되어 있기 때문에 발생합니다. 그러나 참조 호출을 제거하면 TestPildId를 기반으로 TestChild를 쿼리 할 때 다른 오류가 발생합니다. 이 시나리오에 대한 복합 키를 생성하는 방법에 대한

var session = _sessionBuilder.GetSession(); 
using (var tx = session.BeginTransaction()) 
{ 
    // create parent 
    var p = new TestParent() { FavoriteColor = "Red" }; 
    session.Save(p); 

    // creat child 
    var c = new TestChild() 
       { 
        ChildName = "First child", 
        Parent = p, 
        Age = 4 
       }; 
    session.Save(c); // breaks with References call in TestChildMap 

    tx.Commit(); 
} 

// breaks without the References call in TestChildMap 
var children = _sessionBuilder.GetSession().CreateCriteria<TestChild>() 
    .CreateAlias("Parent", "p") 
    .Add(Restrictions.Eq("p.TestParentId", 1)) 
    .List<TestChild>(); 

어떤 아이디어 :

여기에 쿼리를 수행하는 코드는?

답변

11

쿼리 및 삽입이 가능한 더 나은 솔루션을 찾았습니다. 핵심은 레코드를 삽입하지 않기 위해 TestChild 용 맵을 업데이트하는 것입니다. 새지도 :

public class TestChildMap : ClassMap<TestChild> 
{ 
    public TestChildMap() 
    { 
     Table("TestChild"); 
     CompositeId() 
      .KeyProperty(x => x.ChildName, "ChildName") 
      .KeyReference(x => x.Parent, "TestParentId"); 

     Map(x => x.Age); 
     References(x => x.Parent, "TestParentId") 
      .Not.Insert(); // will avoid "Index was out of range" error on insert 
    } 
} 
+1

방금 ​​날 만들었습니다! asker와 answerer에게 큰 감사! 나도 한 방향으로는 삽입하고, 그렇지 않으면 반대 방향으로 작동하지만 해결을 위해 이것을 짐작하지는 못했다. – Sam

+0

해결책은 특히 코드 라인에 맞습니다. 삽입() – Anil

2

당신이 당신의 쿼리를 수정할 수 없습니다 어떤 이유는 단지

_sessionBuilder.GetSession().CreateCriteria<TestChild>() 
    .Add(Restrictions.Eq("Parent.TestParentId", 1)) 
    .List<TestChild>() 

그런 다음 참조를 제거 할 수?

+0

감사합니다. 모든 항목 (다른 쿼리에 대해 TestChild 및 TestParent에 참여해야 할 수도 있음)을 수정할지 모르겠지만 나중에 걱정할 것입니다. –

관련 문제