我今天阅读了一篇关于如何使用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(顶点),但是当我有这样的HasMany关系时,我选择了必须手动将“子对象”插入_session的地方。可能不适合我的确切情况。
PS:映射和模型已针对真实(oracle)数据库进行了测试,它们应该正常工作(至少对于读取数据)。我还使用CheckComponentList而不是CheckList进行了测试,但结果仍然相同。如果我删除“.CheckList(..”行,而只是检查所有其他属性,它工作正常。
希望如果我在这里做错了什么,有人可以启发我。如上所述,这是我的第一个NHibernate映射测试,所以请温柔=)
答案 0 :(得分:1)
HasMany(x => x.Vertices)
没有级联设置,这意味着它根本不会保存您将某些列映射了两次,因为它们已经在compositeId中,所以应删除以下内容
Map(x => x.VertexNumber, "VERTEX_NO");
Map(x => x.AreaId, "AREA_ID");