2012-12-31 91 views
0

我有一個問題,當我嘗試編輯簡單記錄時,在我的表結構中創建了多對多映射,導致頭痛。通過多對多映射更新記錄的問題

例,其中我有問題的佈局:

Facilities Many-to-One Locations 
Facilities One-to-Many Users 
Users Many-to-Many Locations 
Users One-to-Many PreviousPasswords 

如果我做出改變的設備記錄(更改名稱字段)我在保存收到以下錯誤:

集合[網友.PreviousPasswords]沒有被沖洗處理()

映射是這樣的:

public FacilitiesMap() 
{ 
    Table("Facilities"); 

    Id(x => x.ID); 
    Map(x => x.Name); 
    HasMany(x => x.Users).KeyColumn("FacilitiesID").Cascade.AllDeleteOrphan().Inverse(); 
    HasMany(x => x.Locations).KeyColumn("FacilitiesID").Cascade.AllDeleteOrphan().Inverse(); 
} 

public UsersMap() 
{ 
    Table("Users"); 
    Id(x => x.ID); 
    Map(x => x.FirstName); 
    Map(x => x.LastName); 
    References(x => x.Facilities, "FacilitiesID").ForeignKey("ID"); 
    HasMany(x => x.PreviousPasswords).KeyColumn("UsersID").Cascade.AllDeleteOrphan().Inverse(); 
    HasManyToMany<Locations>(x => x.Locations) 
     .Schema("Members") 
     .Table("UsersToLocations") 
     .ParentKeyColumn("UsersID") 
     .ChildKeyColumn("LocationsID") 
     .LazyLoad() 
     .Cascade.SaveUpdate().Inverse(); 
} 

public LocationsMap() 
{ 
    Table("Locations"); 

    Id(x => x.ID); 
    Map(x => x.Name); 
    References(x => x.Facilities, "FacilitiesID").ForeignKey("ID"); 
    HasMany(x => x.Patients).KeyColumn("LocationsID").Cascade.AllDeleteOrphan().Inverse(); 
    HasManyToMany<Users>(x => x.Users) 
     .Schema("Members") 
     .Table("UsersToLocations") 
     .ParentKeyColumn("LocationsID") 
     .ChildKeyColumn("UsersID") 
     .Cascade.SaveUpdate(); 
} 

public PreviousPasswordsMap() 
{ 
    Table("PreviousPasswords"); 

    Id(x => x.ID); 
    Map(x => x.Password); 
    Map(x => x.DateTime); 

    References(x => x.Users, "UsersID").ForeignKey("ID"); 
} 

我可以做一個成功更新到設施記錄的唯一方法是,如果我使用下面的函數變化,並在保存前拿到備案:

public Facilities GetFacility(int id) 
{ 
    return FluentSessionManager.GetSession() 
     .CreateCriteria<Facilities>() 
     .Add(Expression.Eq("ID", id)) 
     .SetFetchMode("Users", FetchMode.Eager) 
     .SetFetchMode("Locations", FetchMode.Eager) 
     .UniqueResult<Facilities>(); 
} 

這種方法的問題是,哪裏有10000用戶需要很長時間來處理此查詢。或者更糟糕的是,如果我們有100個位置,則需要大約2分鐘才能獲得一個設施記錄進行編輯。

我確定映射中存在某種問題。不知道如何解決,甚至從哪裏開始。任何幫助,這將不勝感激。 在此先感謝。

回答

0

你真的需要設施的所有用戶嗎?如果你只添加用戶可以使用

HasMany(x => x.Users).ExtraLazyLoad(); 

,提高查詢時真正需要

public Facilities GetFacility(int id) 
{ 
    var session = FluentSessionManager.GetSession(); 

    // ignore the result, we only want to cache the results in the session 
    session.CreateCriteria<Facilities>() 
     .Add(Expression.Eq("ID", id)) 
     .SetFetchMode("Users", FetchMode.Eager) 
     .Future<Facilities>(); 

    return session.CreateCriteria<Facilities>() 
     .Add(Expression.Eq("ID", id)) 
     .SetFetchMode("Locations", FetchMode.Eager) 
     .FutureValue<Facilities>().Value; 
} 
+0

是對ExtraLazyLoad()在最新的NHibernate的一個新的功能,建立所有子集合?出於某種原因,我沒有將它作爲我正在使用的版本中的一個選項。謝謝。 –

+0

我下載了最新版本,現在我已經爲映射準備了「ExtraLazyLoad()」命令。問題與您的解決方案...用戶映射HasManyToMany不HasMany。我從來沒有與HasMany,或引用映射的問題。就在最近我開始使用HasManyToMany,它導致了各種各樣的胃灼熱。事實證明,如果我不急於加載「用戶」,因爲HasManyToMany映射,我試圖保存時會出現各種錯誤。 –

+0

然後請更正'設施一對多用戶'設置多個用戶在問題中。儘管如此,我發佈的查詢應該在渴望提取時擺脫雙笛卡爾積,並且會緩解一點點的痛苦 – Firo