2012-04-20 10 views
1

私はPolygonMappingのテーブルにpolygon idと他の関連するテーブルのidsが含まれています。このデータベース構造をNHibernateにどのようにマップするのですか?

Polygonテーブルには、IDしか含まれていません。

そのレジスタpolygon_IDが含まれている、それはの一部とpoints_Idstart pointend point)のカップルであるlineテーブルもあります。

pointテーブルは、2 coordinatesXおよびY)のみを含みます。

NHibernate for C#を使用してこのデータベース構造をマップする方法については混乱しています。 のlinesに簡単にアクセスできるようにしたいので(polygonクラスの行のリストを作成するのが良いと思います)、1つを更新したいときはPolygonMappingクラスのみを保存したいと思いますポイントlineまたはpolygonです。私はそれを自動的にしたいと思います。

私を助けてください!

ありがとうございます。

+0

テーブルとエンティティの定義を投稿できますか?あるいは、エンティティについてのヘルプも探していますか? – squillman

+0

エンティティを手助けすることができれば、それは素晴らしいことでしょう。私が定義した方法は、ポストに記述されています。私が解決したい問題は、ポイントに基づいて他のテーブルの情報に関連するポリゴンを構築できることです。私のプログラムでは、ポリゴンクラスとデータベースのラインとポイントを簡単に作成できるようにする必要があります。変更が加えられた場合(ラインの追加やポイントの変更など)、データベースで簡単に更新する必要があります。 – jpnavarini

答えて

1

ポイントを記述するPointオブジェクト、2つのPointオブジェクトを含むLineオブジェクト、 "StartPoint"と "EndPoint"という名前のオブジェクト、およびPolygonオブジェクトの3つのドメインモデルオブジェクトを作成することで、これは、行の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はマッピングファイルを作成することです。これは以下のように行うことができます。親ポリゴンオブジェクトを保存すると子オブジェクトの変更がカスケードされるという要件を満たすために、「カスケード」属性を「すべて」に設定します。それが保存されている場合、あなたの親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(); 
     } 

編集:上記のマッピングは、常にラインのみ、親ポリゴンスルーオブジェクトにアクセスすることを想定してい オブジェクト。線に直接アクセスする場合は、線オブジェクトから多角形の親に多対1の参照を追加することができます。これを行うには、あなたがラインクラスに次のプロパティを追加する必要があります。

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 注場合は、そのポリゴンラインアソシエーションを双方向にするには、グラフの一貫性を確保するためにドメインモデルにコードを追加する必要があります。例えばthis SO postを参照してください。

+0

ありがとうございます!非常に有用で完全な答え!しかし、私はまだ2つの疑問を持っています。まず、どのポリゴンから線が出ているかを調べるにはどうすればいいですか?次に、ポイントの値を更新してポリゴンを保存する場合、値を更新するか、データベースに新しいレジスタを作成しますか?ありがとうございました! – jpnavarini

+0

あなたの質問に答えるには1)最初の投稿では、Polygonの親を介して常にオブジェクトグラフにアクセスすることを前提としています。 Lineオブジェクトに直接アクセスする場合は、子Lineクラスの参照を親Polygonクラスに追加し、対応するマッピングをマッピングファイルに追加します。私はこれを含めるために私の最初の投稿を更新しました。 2)親PolygonオブジェクトからオブジェクトグラフをロードしてPointオブジェクトを更新すると、nHibernateは新しい行を挿入するのではなく、DB内のPoint行を更新します。キーフィールドにデフォルト以外の値があるかどうかに基づいて挿入または更新するかどうかを決定します。 –

+0

ラインクラスに追加したこのポリゴン参照は円の依存関係を作成しますか?私がHibernateを介してポリゴンオブジェクトを保存しようとすると、ポリゴンを指し示すラインを保存しようとせず、ラインをもう一度保存しようとしますか? – jpnavarini

関連する問題