2011-04-20 64 views
2

在我的域模型中,用戶與許多位置關聯 - 通過UserPlace類和映射(與FluentNHibernate)建立關係,如下所示(用戶擁有UserPlace的集合稱爲鄰居在修改與NHibernate的多對多關係時防止刪除/插入

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

每當我修改屬於用戶的任何UserPlace實體,然後保存用戶的分貝,該用戶的所有UserPlace行被刪除,然後重新插入

我認爲這是因爲NHibernate不知道如何從另一個唯一標識這些行之一。換句話說,我的映射中的組件沒有這樣的關鍵字。

主鍵可以通過組合存儲這兩個實體之間關係的表中的User_id和Place_id列來形成。我如何使用Fluent來設置此密鑰?這是否會解決我所看到的刪除和重新插入行爲?

編輯:我問NHUsers這件事,Fabio Maulo建議使用IdBag。就我所知,Fluent NHibernate不支持這種方法 - 組件不允許標識符。我還可以如何映射這種多對多關係並防止刪除所有重新插入所有問題?

編輯2:這裏是NH基於我的映射表

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)) 

有User.Id和Neighbourhood.User_Id之間和Neighbourhood.Place_id和Place.Id

之間的關係FK
+0

它可以幫助顯示用於創建有問題的表的sql。我很難想象這些表格。這聽起來像你需要在UserPlace的映射中的複合ID。如果我能看到表格,爲您提供備用映射可能會更容易。 – 2011-04-24 23:16:20

+0

感謝您的評論。我已經用表格定義更新了這個問題(爲了簡潔起見,我剪掉了非重要的列) – 2011-04-25 13:33:16

回答

1

您可以映射這樣的這種關係,以避免您正在運行到場景:

public class UserMap : ClassMap<User> 
{ 
    HasMany(x => x.Neighbourhood) 
     .KeyColumn("User_id") 
     .Not.LazyLoad().Cascade.SaveUpdate(); 
} 

public class NeighborHoodMap : ClassMap<NeighborHood> 
{ 
    Table("Neighbourhood"); 
     CompositeId() 
      .KeyReference(x => x.User, "User_id") 
      .KeyReference(x => x.Place, "Place_id"); 

    Map(x => x.IsDefault).Not.Nullable(); 
    Map(x => x.Selected).Not.Nullable().Default("0"); 
} 

鄰居類會是這個樣子,那麼:

public class NeighborHood 
{ 
    public virtual User User { get; set; } 
    public virtual Place Place { get; set; } 
    public virtual bool IsDefault { get; set; } 
    public virtual bool Selected { get; set; } 

    public override bool Equals(object obj) 
    { 
     //check here to make sure these objects are equal (user_id and place_id are the same)  
    } 

    public override int GetHashCode() 
    { 
     return User.Id.GetHashCode()^Place.Id.GetHashCode(); 
    } 
} 
+0

克爾清!奇蹟般有效。我讓ReSharper爲我實現Equals()(稍後會檢查它是否好),它就像它應該那樣工作。非常感謝! – 2011-04-25 14:30:15

+0

np,很高興我能幫上忙。 – 2011-04-25 15:10:37

0

我對Fluent並不熟悉,但作爲解決方法,您可以在UserPlace表上定義一個主鍵,以便NH可以跟蹤這些更改。

只是一個想法。