2011-11-18 105 views
0

這是我第一次使用EF的經歷,所以我可能會做一些愚蠢的事情。對建築的任何評論都是值得歡迎的。EF 4定製存儲庫

所以我有典型的用戶類。用戶擁有一個用戶名和角色的列表:

public class User 
{ 
    public string UserID{ get; set; } 
    public List<Role> Roles { get; set; } 
    public int Id { get; set; } 
    public User() 
    { 
     Roles = new List<Role>(); 
    } 
} 

我的域對象生活在自己的代碼庫,爲他們的倉庫接口一起。所以在這種情況下,將會有一個IUserRepository和所有的CRUD方法以及我可能需要的任何專門的數據訪問方法。我想要做的是在另一個類庫中使用EF4實現這些存儲庫接口。到目前爲止,這個設計有什麼問題?

現在在db(sql server)中我有典型的表:Users,Roles和一個多對多表映射用戶角色UsersRoles。

我已經成功地在EF庫中設置了大多數CRUD方法。這裏是保存樣子

public void Save(Drc.Domain.Entities.Staff.User member) 
    { 
     using (var ctx = new DrcDataContext()) 
     { 
      var efUser = MapFromDomainObject(member); 
      if(member.Id < 1) 
      {      
       ctx.Users.AddObject(efUser);      
      } 
      else 
      {        
       ctx.Users.Attach(efUser); 
       ctx.ObjectStateManager.ChangeObjectState(efUser, EntityState.Modified); 
      }   
      ctx.SaveChanges(); 
      member.Id = efUser.UserId;     
     }    
    } 

現在,我不知道這是否是解決這個問題的正確方法,但它的工作原理。但是,我在刪除時遇到了問題。問題是與相關表

public void Delete(Drc.Domain.Entities.Staff.User member) 
    { 
     using (var ctx = new DrcDataContext()) 
     { 
      var efUser = MapFromDomainObject(member); ctx.Users.Attach(efUser); 
      while (efUser.Roles.Count > 0) 
      { 
       ctx.ObjectStateManager.ChangeObjectState(efUser.Roles.First(), EntityState.Deleted); 
      }       
      ctx.SaveChanges(); 
      ctx.ObjectStateManager.ChangeObjectState(efUser, EntityState.Deleted); 
      ctx.SaveChanges(); 
     } 
    } 

如果我不刪除在循環中的角色我得到一個DELETE與參考約束錯誤的衝突。如果我運行上面的代碼,它會刪除多對多表中正確的行,但它也會刪除Roles表中的行。我現在處於一個死衚衕,並考慮在ORO可靠ADO.net中挖掘ORM想法並編寫我的存儲庫實現。

- 編輯我猜這不是用EF實現存儲庫的正確方法。是否有可能在一堆以EF爲中心的東西中亂拋垃圾?

+0

我認爲你的問題更多的是整個連接/分離功能。你應該真的只是從當前上下文中的數據庫中獲取對象,然後修改它們的值。你不應該真的刪除角色,只需刪除efUser(確保它在EF和db中標記爲級聯刪除) –

+0

我想過這個,但我不想打到數據庫去獲取我想刪除的用戶。我想我無論如何都要執行刪除操作,所以我可能會試試這個 – cdaq

+0

如果我使用這種方法,那麼在我保存之前我還得先做一次。狡猾的這不是正確的方式去做。 – cdaq

回答

0

使用簡單的標準方法,並且不與實體狀態陷入混亂:

public void Delete(Drc.Domain.Entities.Staff.User member) 
{ 
    using (var ctx = new DrcDataContext()) 
    { 
     var efUser = MapFromDomainObject(member); 
     ctx.Users.Attach(efUser); 
     ctx.Users.DeleteObject(efUser); 
     ctx.SaveChanges(); 
    } 
} 

通常有從User表數據庫級聯刪除的連接表(如果你沒有手動禁用它)。因此,刪除用戶也會刪除連接表中的相應行(但當然不包括角色)。

將實體的狀態設置爲Deleted與調用DeleteObject不同。它只會將父項設置爲刪除,並使子項在上下文中處於未刪除狀態,導致違反約束的異常。 DeleteObject也將在上下文中標記爲Deleted,因此避免例外。

+0

感謝Slauma這個工程。我還必須打開m:m表的級聯刪除。它默認關閉。我仍然不確定這是我想要走的方向。 – cdaq