2009-07-01 2 views
1

Fluent NHibernate를 사용할 때 홀수 오류가 발생합니다. 나는 당신이 원한다면 나의 "집계 루트"인 Module이라는 엔티티 객체를 가지고있다. Module 클래스와 여러 관련 클래스에 대한 매핑을 만들고 테스트했으며 모든 필드를 채우고 저장 한 Module 만들기를 시도했습니다. 이것은 올바르게 작동했습니다.콜렉션이 Fluent NHibernate로 채워지지 않음

내 문제는 데이터베이스에서 개체를 검색하려고 할 때입니다. Module 객체는 다시 정상적으로 돌아 오지만, 데이터베이스 테이블에있는 객체를 보더라도 그 객체에 포함 된 콜렉션은 모두 비어 있습니다 !! 나는 이것에 손을 쓸 수 있었다. 나는 somone이 도울 수 있기를 바란다!

편집 : 아래의 BuildDeriveModule에 대한 코드가 추가되었습니다.

var dei1 = BuildDeriveModule(); 

var sessionSource = Injector.Resolve<ISessionSource>(); 

using (var session = sessionSource.CreateSession()) 
{ 
    using (var transaction = session.BeginTransaction()) 
    { 
     session.Save(dei1); 
     transaction.Commit(); 
    } 
} 

Module item = null; 
using (var session = sessionSource.CreateSession()) 
{ 
    item = session 
       .CreateCriteria(typeof(Module)) 
       .Add(Restrictions.Eq("ModuleId", dei1.ModuleId)) 
       .UniqueResult<Module>(); 

    Assert.Equal<Module>(dei1, item); 
    Assert.Equal<int>(4, item.Variables.Count); 
} 

내 모듈 클래스는 다음과 같습니다 :

public class Module : Entity, IEntity 
    { 
     public Module() 
     { 
      Variables = new HashedSet<ModuleVariable>(); 
     } 

     public virtual string ModuleId 
     { 
      get; 
      set; 
     } 

     public virtual ISet<ModuleVariable> Variables 
     { 
      get; 
      set; 
     } 

     public virtual Variable StratumVariable 
     { 
      get; 
      set; 
     } 

     public virtual Stratum DefaultStratum 
     { 
      get; 
      set; 
     } 

     public virtual ISet<Stratum> OptionalStrata 
     { 
      get; 
      set; 
     } 

     public virtual DateTime LastUpdated 
     { 
      get; 
      set; 
     } 

     #region Override Methods 

     public override string ToString() 
     { 
      return this.ModuleId; 
     } 

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

      var other = obj as Module; 

      if (other == null) return false; 

      if (other.ModuleId != this.ModuleId) return false; 

      return true; 
     } 

     public override int GetHashCode() 
     { 
      return ModuleId.GetHashCode(); 
     } 

     #endregion 
    } 

: (주 엔티티는 FluentNHibernate.Data.Entity에서 유래) 그리고 내 매핑은 다음과 같습니다

여기

내 테스트입니다
public class ModuleMap : ClassMap<Module> 
{ 
    public ModuleMap() 
    { 
     Id(x => x.Id); 
     Version(x => x.LastUpdated); 
     Map(x => x.ModuleId) 
      .Unique() 
      .Not.Nullable(); 
     HasMany<ModuleVariable>(x => x.Variables) 
      .Inverse() 
      .Cascade.SaveUpdate(); 
     References<Variable>(x => x.StratumVariable) 
      .Not.Nullable() 
      .Cascade.SaveUpdate(); 
     References<Stratum>(x => x.DefaultStratum) 
      .Not.Nullable() 
      .Cascade.SaveUpdate(); 
     HasMany<Stratum>(x => x.OptionalStrata) 
      .Inverse() 
      .Cascade.SaveUpdate(); 
    } 
} 

BuildDeriveModule의 코드 :

개인 모듈 BuildDeriveModule() { var에 pp01 = 새로운 관계 { RelationId = "PP01" };

 var hh01 = new Relation 
     { 
      RelationId = "HH01" 
     }; 

     var stdei1 = new Variable 
     { 
      VariableId = "STDEI1", 
      Relation = pp01 
     }; 

     var frameId = new Variable 
     { 
      VariableId = "FRAME_ID", 
      Relation = pp01 
     }; 

     var persno = new Variable 
     { 
      VariableId = "PERSNO", 
      Relation = pp01 
     }; 

     var hp = new Driver 
     { 
      Name = "HP", 
      Phase = 1 
     }; 

     hp.KeyVariables.Add(frameId); 
     hp.KeyVariables.Add(persno); 

     var r2p1 = new Variable 
     { 
      VariableId = "R2P1", 
      Relation = pp01 
     }; 

     var age = new Variable 
     { 
      VariableId = "AGE", 
      Relation = pp01 
     }; 

     var marst = new Variable 
     { 
      VariableId = "MARST", 
      Relation = pp01 
     }; 

     var doctp = new Variable 
     { 
      VariableId = "DOCTP", 
      Relation = hh01 
     }; 

     pp01.AddVariable(stdei1); 
     pp01.AddVariable(r2p1); 
     pp01.AddVariable(age); 
     pp01.AddVariable(marst); 
     hh01.AddVariable(doctp); 

     var defaultStratum = new Stratum 
     { 
      Number = -1, 
      Driver = hp 
     }; 

     var dei1 = new Module 
     { 
      ModuleId = "DEI1", 
      StratumVariable = stdei1, 
      DefaultStratum = defaultStratum 
     }; 

     var mv_r2p1 = new ModuleVariable 
     { 
      ModuleId = dei1, 
      VariableId = "R2P1", 
      UploadId = r2p1, 
      DownloadId = r2p1, 
      HasSubunits = true 
     }; 

     var mv_age = new ModuleVariable 
     { 
      ModuleId = dei1, 
      VariableId = "AGE", 
      UploadId = age, 
      DownloadId = age, 
      HasSubunits = true 
     }; 

     var mv_marst = new ModuleVariable 
     { 
      ModuleId = dei1, 
      VariableId = "MARST", 
      UploadId = marst, 
      DownloadId = marst, 
      HasSubunits = true 
     }; 

     var mv_doctp = new ModuleVariable 
     { 
      ModuleId = dei1, 
      VariableId = "DOCTP", 
      UploadId = doctp, 
      DownloadId = doctp, 
      HasSubunits = false 
     }; 

     dei1.AddVariable(mv_r2p1); 
     dei1.AddVariable(mv_age); 
     dei1.AddVariable(mv_marst); 
     dei1.AddVariable(mv_doctp); 

     return dei1; 
    } 
+0

BuildDeriveModule()에 대한 코드를 추가 할 수 있습니까? – Nigel

+0

완료! 미리 감사드립니다! –

답변

0

OK, 나는 그것이 작동있어 생각 . 나는 Thin 줄에서 .Inverse()를 제거했다. ModuleMap에서 단위 테스트가 작동하고

HasMany<ModuleVariable>(x => x.Variables) 
      .Inverse() 
      .Cascade.SaveUpdate(); 

을 제거했다. 나는 왜 그런지 잘 모르겠다. 그래서 누군가가 그것을 지적 할 수 있다면 그것을 인정할 것이다.

+2

죄송합니다. 너무 늦었 습니다만,이 속성을 지나치는 사람은 하위 항목이 콜렉션에서 존재를 유지할 책임이 있음을 의미합니다. 이것은 일반적으로 참조를 부모에게 돌려주는 것을 의미합니다. 이 방법으로 도메인 개체를 설정하지 않은 경우 사용자가 보았던 동작이 설명됩니다. – AlexCuse

+0

훌륭한 설명 Alex, 고마워. 그것은 Inverse를 멋지게 요약합니다. –

관련 문제