2009-07-01 21 views
1

Fluent NHibernateを使用しているときに奇妙なエラーが発生しています。私はあなたがする場合、私の "集約ルート"であるモジュールと呼ばれるエンティティオブジェクトがあります。私は、Moduleクラスとさまざまな関連クラスのマッピングを作成してテストし、すべてのフィールドを記入して保存してModuleを作成しようとしました。これは正しく機能しました。コレクションにFluent NHibernateが設定されていません

私の問題は、データベースからオブジェクトを取得しようとするときです。 Moduleオブジェクトは元に戻ってきますが、データベーステーブルのオブジェクトを参照しても、その中に含まれるコレクションはすべて空です!私は本当にこの1つに手を使用することができます、私はsomoneが助けることを願っています!

edit:下記のBuildDeriveModuleのコードが追加されました。ここで

は私のテストである:(注::エンティティがFluentNHibernate.Data.Entityから来ている)

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); 
} 

マイModuleクラスは次のようになります

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 
    } 

そして、私のマッピングは次のようになります。

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、私はそれが動作するようになったを考える。私は、ModuleMap内の細線から.Inverse()を削除しました。

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

ModuleMapでユニットテストが機能しました。私は確かになぜそれほど確かではないので、もし誰でもそれを指摘できれば、それは評価されるだろう。

+2

残念ですが、これは非常に遅いですが、これを越えている人にとって、inverseプロパティは、子エンティティがコレクション内にその存在を維持する責任があることを意味します。これは、通常、参照を親に戻すことを意味します。あなたのドメインオブジェクトがこのように設定されていないと、それはあなたが見た動作を説明するでしょう。 – AlexCuse

+0

優秀な説明アレックス、ありがとう。それはInverseをうまくまとめます。 –