0

今日、PersistenceSpecification クラスを使用して Fluent NHibernate マッピングをテストする方法に関するブログ記事を読みました。とてもいいアイデアだと思ったので、やってみました。ただし、HasMany 関係をチェックするときに System.ArgumentOutOfRangeException をスローし続けます。テストには SQL Lite インメモリ データベースを使用します。

これが私のモデルの外観です。私はいくつかの無関係なプロパティなどを切り取った:

public class Area
{
    public virtual int AreaId{ get; set; }
    public virtual IList<AreaPolygonVertex> Vertices { get; set; }
    ...
}

public class AreaPolygonVertex
{
    public virtual Point Point { get; set; }
    public virtual int VertexNumber { get; set; }
    public virtual int AreaId { get; set; }
}

public class Point
{
    public double X {get; set;}
    public double Y {get; set;}
}

NHibernate のマッピングは次のとおりです。

public class AreaMap : ClassMap<Area>
    {
        public AreaMap()
        {
            Table("VIEW_AREAS");
            Id(x => x.AreaId, "ID");
            HasMany(x => x.Vertices).KeyColumn("AREA_ID");
            ...
        }
    }

  public class AreaPolygonVertexMap : ClassMap<AreaPolygonVertex>
  {
      public AreaPolygonVertexMap()
      {
          Table("AREA_POLYGON_VERTICES");
          CompositeId()
                .KeyProperty(x => x.AreaId, "AREA_ID")
                .KeyProperty(x => x.VertexNumber, "VERTEX_NO");

          Component(x => x.Point, m =>
          {
              m.Map(x => x.X, "X");
              m.Map(x => x.Y, "Y");
          });

          Map(x => x.VertexNumber, "VERTEX_NO");
          Map(x => x.AreaId, "AREA_ID");
      }
  }

そして最後にテスト:

[Test]
public void should_map_areas_correctly()
{
     var vertex = new AreaPolygonVertex {
          AreaId = 1, 
          Point = new Point(20, 30), 
          VertexNumber = 1
      };

      _session.Save(vertex);

      new PersistenceSpecification<Area>(_session)
            .CheckProperty(c => c.AreaId, 1)
            .CheckList(c => c.Vertices, new List<AreaPolygonVertex>{ vertex })
            .VerifyTheMappings();
 }

これは ArgumentOutOfRangeException をスローし、「インデックスは範囲外です。負ではなく、コレクションのサイズよりも小さい必要があります。パラメータ名: インデックス」と伝えます。この例外では、それほど有用な情報はないようです。

最初は、検証呼び出しを実行する前に _session.Save(vertex) を実行しませんでしたが、このような HasMany 関係がある場合、「子オブジェクト」を _session に手動で挿入する必要がある場所を見つけました。ただし、私の正確なシナリオには適していない可能性があります。

PS: マッピングとモデルは実際の (オラクル) DB に対してテストされており、(少なくともデータの読み取りでは) 正常に動作するはずです。また、CheckList の代わりに CheckComponentList を使用してテストしましたが、結果は同じです。「.CheckList(..」行を削除し、代わりに他のすべてのプロパティをチェックすると、正常に動作します。

ここで何か間違ったことをしている場合、誰かが私を啓発してくれることを願っています。前述のように、これは私の最初の NHibernate マッピング テストなので、優しくしてください =)

4

1 に答える 1

1
  • HasMany(x => x.Vertices)Cascading セットがないため、まったく保存されません
  • 一部の列を 2 回マップした場合、以下は既に compositeId に含まれているため、削除する必要があります

    Map(x => x.VertexNumber, "VERTEX_NO");
    Map(x => x.AreaId, "AREA_ID");
    
于 2012-08-14T07:38:01.890 に答える