FluentNHibernate отображение составных внешних ключей - PullRequest
1 голос
/ 11 апреля 2010

У меня есть существующая схема базы данных и я хочу заменить пользовательский код доступа к данным на 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
  )
)

Существующая модель предметной области имеет следующую структуру классов:

альтернативный текст http://yuml.me/4e2bcb95

Класс Property содержит другие члены, представляющие имя и значение свойства. Классы ContainerProperty и ItemProperty не имеют дополнительных членов. Они существуют только для идентификации владельца недвижимости. Классы Container и Item имеют методы, которые возвращают коллекции ContainerProperty и ItemProperty соответственно. Кроме того, класс Container имеет метод, который возвращает коллекцию всех объектов Property в графе объектов. Я думаю, что это был либо удобный метод, либо устаревший метод, который никогда не удалялся.

Бизнес-логика в основном работает с Item (в качестве совокупного корня) и работает только с Контейнером при добавлении или удалении Item.

Я пробовал несколько методов для сопоставления этого, но ни один из них не работает, поэтому я не буду включать их здесь, если кто-то их не попросит. Как бы вы это отобразили?

1 Ответ

1 голос
/ 27 апреля 2011

Отображение должно выглядеть так:

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