简体   繁体   English

如何将此数据库结构映射到NHibernate?

[英]How to map this database structure into NHibernate?

I have a table which PolygonMapping whose register contains a polygon id and other ids of other related tables. 我有一个表,其中PolygonMapping的寄存器包含一个polygon id和其他相关表的其他ID。

The Polygon table only contains its ID . Polygon表仅包含其ID

There is also the line table, whose register contains the polygon_ID it is part of and a couple of points_Id ( start point and end point ). 还有一个line表,它的寄存器包含它的一部分polygon_ID和几个points_Idstart pointend point )。

The point table contains 2 coordinates only ( X and Y ). point表仅包含2个coordinatesXY )。

I am confused about how to map this database structure using NHibernate for C#. 我对如何使用NHibernate for C#映射此数据库结构感到困惑。 I would like to be able to easily access the lines of a polygon (so I think having a list of lines in the polygon class would be good), and I would like to able to save only the PolygonMapping class when I want to update one point, line or polygon . 我希望能够轻松地访问polygonlines (因此,我认为在polygon类中具有线的列表会很好),并且当我想更新一个polygon时,我只希望保存PolygonMapping类点, linepolygon I would like to have it done automatically. 我想自动完成。

Please help me! 请帮我!

Thank you. 谢谢。

I would map this problem by creating three domain model objects: a Point object that describes a point, a Line object that contains a two Point objects, one named "StartPoint" and one named "EndPoint", and a Polygon object that contains an IEnumerable of Lines. 我将通过创建三个域模型对象来映射此问题:一个描述一个点的Point对象,一个包含两个Point对象的Line对象,一个名为“ StartPoint”和一个名为“ EndPoint”的对象以及一个包含IEnumerable的Polygon对象行。 The domain objects would look like this: 域对象如下所示:

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; }
}

You could persist this class using a database schema that has a table for each domain model object. 您可以使用为每个域模型对象都有一个表的数据库模式来持久化此类。 数据库架构

The SQL DDL to create this database structure is as follows: 创建此数据库结构的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)
)

Your final task is to write your nHibernate mapping file to map the domain model to the underlying database tables. 最后的任务是编写nHibernate映射文件,以将域模型映射到基础数据库表。 This can be done as shown below. 可以如下所示进行。 Note that I set the "cascade" attributes to "all" to meet your requirement that saving the parent Polygon object cascades the changes to the child objects. 请注意,我将“层叠”属性设置为“全部”,以满足您保存父多边形对象将更改级联到子对象的要求。

  <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>

With this mapping you can manipulate your parent Polygon object and the entire object graph will be persisted to the database when it is saved. 使用此映射,您可以操作父Polygon对象,并且整个对象图在保存时将保留在数据库中。 For example, to add a new Line to a Polygon object, you can use the following code snippet: 例如,要向Polygon对象添加新的Line,可以使用以下代码片段:

        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();
         }

Edit: The above mapping assumes that you always want to access Line objects only thru the parent Polygon object. 编辑:上面的映射假定您始终只想通过父Polygon对象访问Line对象。 If you want to access Lines directly, you may want to add a many-to-one reference from the Line object to the Polygon parent. 如果要直接访问“线”,则可能需要从“线”对象向“多边形”父级添加多对一引用。 To do this, you will need to add the following property to the Line class: 为此,您需要将以下属性添加到Line类:

 public Polygon Polygon {get; set;}

as well adding the corresponding mapping in the Line mapping file: 以及在“线”映射文件中添加相应的映射:

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

With these changes, you should now be able to directly load a Line object that contains it's Polygon parent: 通过这些更改,您现在应该能够直接加载包含其Polygon父级的Line对象:

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

Edit 2 Note that if you make the Polygon-Line association bidirectional, you will need to add code to your domain model to ensure graph consistency. 编辑2请注意,如果使Polygon-Line关联为双向,则需要向域模型中添加代码以确保图形的一致性。 See for example this SO post . 例如,参见此SO post

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM