2010-04-10 129 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; 
     } 
    } 
}