FluentNHibernate复合外键的映射

时间:2010-04-10 20:24:18

标签: c# nhibernate fluent-nhibernate nhibernate-mapping

我有一个现有的数据库架构,并希望用Fluent.NHibernate替换自定义数据访问代码。数据库架构无法更改,因为它已存在于运输产品中。并且最好是域对象没有改变或只是最小化。

我无法映射使用以下表结构说明的一个异常模式构造:

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

Property类包含表示属性名称和值的其他成员。 ContainerProperty和ItemProperty类没有其他成员。它们仅用于识别财产的所有者。 Container和Item类具有分别返回ContainerProperty和ItemProperty集合的方法。此外,Container类有一个方法,它返回对象图中所有Property对象的集合。我最好的猜测是,这可能是一种方便的方法,也可能是一种从未被删除的遗留方法。

业务逻辑主要与Item(作为聚合根)一起使用,并且仅在添加或删除Items时与Container一起使用。

我已经尝试了几种技术来映射这个但没有工作,所以我不会在这里包含它们,除非有人要求它们。你会如何映射这个?

1 个答案:

答案 0 :(得分: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. 所有属性和方法都应该是虚拟/覆盖的!
  3. -

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