2012-11-28 40 views
0

有點好奇心。我有一個用戶對象,其中包含每個UserPhoto,UserMatchInterest,UserPreference對象的包。我已經給包中的每個項目引用了父級用戶,並且使用了nhibernate,我已經對雙向映射進行了排序,以便當您第一次創建用戶對象時,它會自動創建UserPhoto,UserMatchInterest和UserPreference對象收集袋,將UserId設置爲父用戶對象,即可正常工作。在NHibernate中更新包項目合併

作爲示例,UserPhoto表具有PhotoId PK列和UserId FK列。 UserPhoto對象具有PhotoId屬性和一個User屬性(不是UserId),所以不是持有UserId,而是擁有對父級的引用並根據用戶PK填充數據庫列。

我遇到的問題是當我想一次性更新用戶對象。用戶對象的其餘部分更新正常,但涉及到照片時,它會在數據庫中創建新照片。我可以理解爲什麼,因爲它們根本沒有鏈接到之前的照片會話對象,因爲這是一個ASP.NET網站,我將處理分離的對象。但它留下了舊的。所以如果你有照片ID 1 & 2,UserId = 1。更新後,您將擁有UserId = 1的照片1,2,3 & 4。我想要的是將圖片1 & 2刪除,然後插入3 & 4。

我曾試圖獨立檢索它們作爲一個集合,並在交易第一刪除它們,但我得到的消息

Message = "deleted object would be re-saved by cascade (remove deleted object from associations) 

代碼刪除如下

// First delete existing photos, interests and preferences 


     var photos = from row in repository.GetItemsAsQuery<UserPhoto>() 
        where row.User.UserId == user.UserId 
        select row; 
     repository.DeleteItems(photos.ToList()); 

     var interests = from row in repository.GetItemsAsQuery<UserMatchInterest>() 
         where row.User.UserId == user.UserId 
         select row; 
     repository.DeleteItems(interests.ToList()); 

     var preferences = from row in repository.GetItemsAsQuery<UserPreference>() 
          where row.User.UserId == user.UserId 
          select row; 
     repository.DeleteItems(preferences.ToList()); 

     // Now update the user object and re-add the above linked items 
     repository.UpdateItem(user); 

的錯誤拋出在repository.DeleteItems(interests.ToList());行,第一次刪除傳遞正常 - 雖然它都在一個事務中。

我的問題是我接近這個正確的方式來更新數據庫中的一個對象,它還需要更新其他對象的包?我沒有辦法在沒有手動設置ID的情況下更新現有的照片對象 - 並且用戶可能已經替換了所有照片或者添加/刪除,因此刪除現有照片並重新添加新照片可能更清晰,但是如何刪除現有照片沒有得到這個級聯錯誤?

回答

0

從你的描述我設想以下類

public class User 
{ 
    public virtual int Id { get; set; } 

    public virtual ICollection<Photo> Photos { get; private set; } 
} 

public class Photo 
{ 
    public User Parent { get; set; } 
    public virtual string Name { get; set; } 
    public virtual byte[] Data { get; set; } 
} 

則映射會是什麼樣

public class UserMap : ClassMap<User> 
{ 
    public UserMap() 
    { 
     Id(x => x.Id); 

     HasMany(x => x.Photos) 
      .AsSet() // no duplicate entries, allows NH to optimise some things 
      .Cascade.AllDeleteOrphan() 
      .Component(c => 
      { 
       c.ParentReference(x => x.Parent); 
       c.Map(x => x.Name); 
       c.Map(x => x.Data); 
      }); 
    } 
} 

注:Cascade.AllDeleteOrphan將刪除所有的全自動孩子不屬於集合的一部分不再