今日、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 マッピング テストなので、優しくしてください =)