FluentNHibernate mapping of composite foreign keys
- by Faron
I have an existing database schema and wish to replace the custom data access code with Fluent.NHibernate. The database schema cannot be changed since it already exists in a shipping product. And it is preferable if the domain objects did not change or only changed minimally.
I am having trouble mapping one unusual schema construct illustrated with the following table structure:
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
)
)
The existing domain model has the following class structure:
The Property class contains other members representing the property's name and value. The ContainerProperty and ItemProperty classes have no additional members. They exist only to identify the owner of the Property. The Container and Item classes have methods that return collections of ContainerProperty and ItemProperty respectively. Additionally, the Container class has a method that returns a collection of all of the Property objects in the object graph. My best guess is that this was either a convenience method or a legacy method that was never removed.
The business logic mainly works with Item (as the aggregate root) and only works with a Container when adding or removing Items.
I have tried several techniques for mapping this but none work so I won't include them here unless someone asks for them. How would you map this?