2012-04-20 95 views
1

我有一個表,其中PolygonMapping其註冊表中包含polygon id和其他相關表的其他ID。如何將這個數據庫結構映射到NHibernate中?

Polygon表只包含其ID

也有line表,其寄存器包含polygon_ID它的一部分和一對夫婦的points_Idstart pointend point)。

point表僅包含2 coordinatesXY)。

我很困惑如何映射這個數據庫結構使用NHibernate的C#。我希望能夠輕鬆訪問polygonlines(所以我認爲polygon類中的行列表會更好),並且我希望只能在保存PolygonMapping類時更新一個類點,linepolygon。我想自動完成它。

請幫幫我!

謝謝。

+0

你可以發佈你的表和實體定義嗎?或者你是否也在尋找實體的幫助? – squillman 2012-04-20 22:06:53

+0

如果你可以幫助實體,那也會很棒。我已經定義的方式在文章中描述。我想解決的問題是能夠基於點建立與其他表格信息相關的多邊形。在我的程序中,我需要能夠輕鬆地構建多邊形類,以及數據庫中的線條和點,並且如果進行了任何更改(添加了線條或更改了點),我需要輕鬆地在數據庫中對其進行更新。 – jpnavarini 2012-04-21 11:14:37

回答

1

我會通過創建三個域模型對象來映射此問題:描述點的Point對象,包含兩個Point對象,一個名爲「StartPoint」和一個名爲「EndPoint」的Line對象以及一個Polygon對象包含IEnumerable行。域對象應該是這樣的:

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

你可以使用對每個域模型對象的表的數據庫架構堅持這個類。 Database Schema

的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的映射文件映射域模型的基礎數據庫表。這可以按照如下所示完成。請注意,我將「cascade」屬性設置爲「all」以滿足您的要求,即保存父級Polygon對象會將更改級聯到子對象。當它被保存

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

有了這個映射,你可以操縱你的父母多邊形對象,整個對象的圖表將被保存到數據庫。例如,一個新的行添加到一個多邊形對象,可以使用下面的代碼片段:

 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對象的多對一引用添加到Polygon父邊。要做到這一點,你需要將以下屬性添加到行類:

public Polygon Polygon {get; set;} 

以及增加在線路映射文件對應的映射:

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

有了這些變化,你現在應該能夠直接加載一個包含它的行對象是多邊形父:

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

編輯2 注意,如果您將Polygon-Line關聯設爲雙向,您需要將代碼添加到您的域模型以確保圖形一致性。例如參見this SO post

+0

非常感謝!非常有幫助和完整的答案!然而,我仍然有兩個疑問:首先,我怎樣才能找出一條線是哪個多邊形的一部分(我將不得不通過所有多邊形列表來查找)?其次,例如,如果我更新點的值,並保存多邊形,它會更新值還是在數據庫中創建新的寄存器?謝謝! – jpnavarini 2012-04-23 12:33:43

+0

回答你的問題1)初始文章假定你總是想通過Polygon父節點訪問對象圖。如果要直接訪問Line對象,請將子Line類中的引用添加回父Polygon類,並將相應的映射添加到映射文件。我已經更新了我的初始文章以包含此內容。 2)如果從父Polygon對象加載對象圖並更新Point對象,nHibernate將更新數據庫中的Point行,而不是插入新行。它根據鍵字段是否具有非默認值來確定是插入還是更新。 – 2012-04-23 14:24:24

+0

這個多邊形引用是否添加到線類創建一個圓的依賴?當我嘗試通過Hibernate保存多邊形對象時,是否會嘗試保存指向多邊形的線並嘗試將線重新保存? – jpnavarini 2012-04-23 16:48:05

相關問題