2010-04-10 151 views
1

我有一個現有的數據庫模式,並希望用Fluent.NHibernate替換自定義數據訪問代碼。由於數據庫模式已經存在於發貨產品中,因此無法更改。如果域對象沒有改變或者只是最小化改變,這是最好的。FluentNHibernate複合外鍵映射

我無法映射具有以下表結構示出的一個不同尋常的模式構建體:

CREATE TABLE [Container] (
    [ContainerId] [uniqueidentifier] NOT NULL, 
    CONSTRAINT [PK_Container] PRIMARY KEY (
    [ContainerId] ASC 
) 
) 

CREATE TABLE [Item] (
    [ItemId]  [uniqueidentifier] NOT NULL, 
    [ContainerId] [uniqueidentifier] NOT NULL, 
    CONSTRAINT [PK_Item] PRIMARY KEY (
    [ContainerId] ASC, 
    [ItemId] ASC 
) 
) 

CREATE TABLE [Property] (
    [ContainerId] [uniqueidentifier] NOT NULL, 
    [PropertyId] [uniqueidentifier] NOT NULL, 
    CONSTRAINT [PK_Property] PRIMARY KEY (
    [ContainerId] ASC, 
    [PropertyId] ASC 
) 
) 

CREATE TABLE [Item_Property] (
    [ContainerId] [uniqueidentifier] NOT NULL, 
    [ItemId]  [uniqueidentifier] NOT NULL, 
    [PropertyId] [uniqueidentifier] NOT NULL, 
    CONSTRAINT [PK_Item_Property] PRIMARY KEY (
    [ContainerId] ASC, 
    [ItemId]  ASC, 
    [PropertyId] ASC 
) 
) 

CREATE TABLE [Container_Property] (
    [ContainerId] [uniqueidentifier] NOT NULL, 
    [PropertyId] [uniqueidentifier] NOT NULL, 
    CONSTRAINT [PK_Container_Property] PRIMARY KEY (
    [ContainerId] ASC, 
    [PropertyId] ASC 
) 
) 

現有的域模型具有下面的類結構:

alt text http://yuml.me/4e2bcb95

物業類包含代表該物業名稱和價值的其他成員。 ContainerProperty和ItemProperty類沒有其他成員。它們僅用於識別物業的所有者。 Container和Item類具有分別返回ContainerProperty和ItemProperty集合的方法。另外,Container類有一個方法,它返回對象圖中所有Property對象的集合。我最好的猜測是,這是一種方便的方法或從未被刪除的傳統方法。

業務邏輯主要與Item(作爲聚合根)一起工作,並且僅在添加或移除Items時才與Container一起工作。

我已經嘗試了幾種技術來映射這個,但沒有工作,所以我不會在這裏包括他們,除非有人問他們。你如何繪製這個圖?

回答

1

映射應該這樣看:

public sealed class CategoryMap : ClassMap<Category> 
{ 
    public CategoryMap() 
    { 
     Table("Categories"); 
     CompositeId() 
      .KeyProperty(c => c.ItemId, "ItemId") 
      .KeyProperty(c => c.CategoryId, "CategoryId"); 
    } 
} 

注:

  1. 類別的實體類應覆蓋的equals()的GetHashCode()方法
  2. 所有屬性和應方法被虛擬/覆蓋!

-

public class Category 
{ 
    public virtual int ItemId { get; set; } 
    public virtual int CategoryId { get; set; } 

    public override bool Equals(object obj) 
    { 
     if (ReferenceEquals(null, obj)) return false; 
     if (ReferenceEquals(this, obj)) return true; 
     if (obj.GetType() != typeof (Category)) return false; 
     return Equals((Category) obj); 
    } 

    public virtual bool Equals(Category other) 
    { 
     if (ReferenceEquals(null, other)) return false; 
     if (ReferenceEquals(this, other)) return true; 
     return other.ItemId == ItemId && other.CategoryId == CategoryId; 
    } 

    public override int GetHashCode() 
    { 
     unchecked 
     { 
      return (ItemId*397)^CategoryId; 
     } 
    } 
}