1

我有一个表,PolygonMapping其寄存器包含polygon id其他相关表的一个和其他 ID。

Polygon表仅包含其ID.

还有一个line表,它的寄存器包含polygon_ID它的一部分和几个points_Idstart pointend point)。

point表仅包含 2 个coordinates(XY)。

我对如何使用 NHibernate for C# 映射此数据库结构感到困惑。我希望能够轻松访问linesa polygon(所以我认为在polygon类中有一个行列表会很好),并且PolygonMapping当我想更新一个点时,我希望能够只保存类,line或者polygon. 我想让它自动完成。

请帮我!

谢谢你。

4

1 回答 1

1

我将通过创建三个域模型对象来映射这个问题:一个描述点的 Point 对象,一个包含两个 Point 对象的 Line 对象,一个名为“StartPoint”,一个名为“EndPoint”,以及一个包含 IEnumerable 的 Polygon 对象行。域对象如下所示:

public class Point
{
    public int Id { get; set; }
    public int XVal {get; set;}
    public int YVal {get; set;}
}

public class Line
{
    public int Id {get; set;}
    public Point StartPoint {get; set;}
    public Point EndPoint {get; set;}
}
public class Polygon
{
    public Polygon()
    {
        Lines = new HashSet<Line>();
    }
    public int Id {get; set;}
    public string Description { get; set; }
    public ICollection<Line> Lines { get; set; }
}

您可以使用具有每个域模型对象的表的数据库模式来持久保存此类。 数据库模式

创建此数据库结构的 SQL DDL 如下:

create table Point
(
    PointId int primary key identity(1, 1),
    XVal int,
    YVal int
)

create table Polygon
(
    PolygonId int primary key identity(1, 1),
[Description] nvarchar(255)
)

create table Line
(
    LineId int primary key identity(1, 1),
    PolygonId int foreign key references Polygon(PolygonId),
    StartPointId int foreign key references Point(PointId),
    EndPointId int foreign key references Point(PointId)
)

您的最后一项任务是编写您的 nHibernate 映射文件以将域模型映射到底层数据库表。这可以如下所示完成。请注意,我将“级联”属性设置为“全部”以满足您保存父多边形对象将更改级联到子对象的要求。

  <class name="Polygon" table="Polygon" lazy="false" >
    <id name="Id" column="PolygonId">
      <generator class="identity" />
    </id>
    <property name="Description" column="Description" />
    <set name="Lines" table="Line" lazy="false" cascade="all">
      <key column="PolygonId" />
      <one-to-many class="Line"  />
    </set>
  </class>

  <class name="Line" table="Line" lazy="false">
    <id name="Id" column="LineId">
      <generator class="identity" />
    </id>
    <many-to-one name="StartPoint" column="StartPointId" class="Point" cascade="all"/>
    <many-to-one name="EndPoint" column="EndPointId" class="Point" cascade="all"/>
  </class>
</hibernate-mapping>

使用此映射,您可以操作父多边形对象,并且整个对象图将在保存时持久保存到数据库中。例如,要将新 Line 添加到 Polygon 对象,可以使用以下代码段:

        using (var session = factory.OpenSession())
        using(var tran = session.BeginTransaction())
        {
           var newPoint = session.Get<Point>(5);
           var newPoint2 = session.Get<Point>(2);
           var newLine = new Line { StartPoint = newPoint, EndPoint = newPoint2 };
            var foo2 = session.Get<Polygon>(1);
            foo2.Lines.Add(newLine);
            session.SaveOrUpdate(foo2);
            tran.Commit();
         }

编辑: 上面的映射假设你总是想通过父多边形对象访问 Line 对象。如果您想直接访问 Lines,您可能需要将 Line 对象的多对一引用添加到 Polygon 父对象。为此,您需要将以下属性添加到 Line 类:

 public Polygon Polygon {get; set;}

以及在 Line 映射文件中添加相应的映射:

<many-to-one class="Polygon" name="Polygon" lazy="false"  />

通过这些更改,您现在应该能够直接加载包含其 Polygon 父级的 Line 对象:

var line = session.Get<Line>(5);
var parent = line.Polygon;

编辑 2 请注意,如果您将 Polygon-Line 关联设为双向,则需要将代码添加到域模型以确保图形一致性。例如,请参阅此 SO 帖子

于 2012-04-22T20:54:32.367 回答