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:映射和模型已经针对真实(oracle)数据库进行了测试,它们应该可以正常工作(至少对于读取数据)。我也使用 CheckComponentList 而不是 CheckList 进行了测试,但结果仍然相同。如果我删除“.CheckList(..”行,而只是检查所有其他属性,它工作正常。

如果我在这里做错了什么,希望有人能启发我。如前所述,这是我的第一个 NHibernate 映射测试,所以要温柔 =)

4

1 回答 1

1
  • HasMany(x => x.Vertices)没有级联集,这意味着它根本不会保存它
  • 您将某些列映射了两次,应删除以下内容,因为它们已经在 CompositeId 中

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