In my domain model a User is associated with many Places - the relationship is modelled via a UserPlace class and a mapping (with FluentNHibernate) as follows (the User has a collection of UserPlace called Neighbourhood:
public class UserMap : ClassMap<User>
{
HasMany(x => x.Neighbourhood)
.Component(c =>
{
c.Map(x => x.IsDefault).Not.Nullable();
c.Map(x => x.Selected).Not.Nullable().Default("0");
c.References(x => x.Place).Fetch.Join();
}
).Not.LazyLoad().Cascade.SaveUpdate();
}
Whenever I modify any UserPlace entity belonging to a user and then persist the user to the db, all UserPlace rows for that user are deleted and then re-inserted.
I assume this is because NHibernate doesn't know how to uniquely identify one of these rows from another. In other words, the component in my mapping doesn't have a key as such.
A primary key can be formed by combining the User_id and Place_id columns in the table that stores the relationship between these two entities. How can I set up this key using Fluent? And will this solve the delete-and-re-insert behaviour that I'm seeing?
EDIT: I asked on NHUsers about this and Fabio Maulo suggested using an IdBag. This isn't supported in Fluent NHibernate as far as I can tell - and components don't allow identifiers. How else can I map this many-to-many relationship and prevent the delete-all-reinsert-all issue?
EDIT 2: Here are the tables that NH generate based on my mappings
CREATE TABLE [dbo].[User](
[Id] [uniqueidentifier] NOT NULL,
--- a bunch of unimportant fields
CONSTRAINT [PK__User] PRIMARY KEY CLUSTERED ([Id] ASC))
CREATE TABLE [dbo].[Neighbourhood](
[User_id] [uniqueidentifier] NOT NULL,
[IsDefault] [bit] NOT NULL,
[Place_id] [int] NOT NULL,
[Selected] [bit] NOT NULL)
CREATE TABLE [dbo].[Place](
[Id] [int] IDENTITY(1000,1) NOT NULL,
--- a bunch of unimportant fields
CONSTRAINT [PK_Place] PRIMARY KEY CLUSTERED ([Id] ASC))
There is a FK relationship between User.Id and Neighbourhood.User_Id and between Neighbourhood.Place_id and Place.Id