none
關於Entity Frmaework中EntityCollection<T>的Remove行為 RRS feed

  • 問題

  • hi...有個問題想請教大家

    假設Domain有個訂單、訂單明細關係
    於是Table為Order,OrderDetail,中間設有關連(FK)
    轉至EF(ORM)後會有Order物件,Order下會有Order.OrderDetail集合

    當執行從集合中移除一筆明細資料這個動作時
    Order.OrderDetail.Remove(orderDetail)
    可能會有兩個意義
    1.移除之間關連性,意謂著該Child資料的Parent已經不是原Parent
    2.刪除Child的資料,意謂著我以不需要該筆Child,因為該Child會被刪除

    目前感覺上EF比較像是第一種意義
    如果我想實作第二種意義,有什麼好的解法嗎?
    (最直接的解法當然就是Context.DeleteObject(child物件)

    2009年4月30日 上午 05:39

解答

  • Entity Framework對於一對多的情況刪除子集合元素必須要手動.
    所以你的想法在EF中無法實現


    但我覺得這點做法其實比較好
    因為自動刪除功能在實做上會遇到很多問題(以前用NHibernate時最後都改用手動).

    至於原因你可以研究一下NHibernate中PO/PJ的問題,實際上ORM要支援這功能在邏輯上有些狀況會產生衝突狀況導致並不好用,所以在EF中改為由使用者自行決定.
    • 已標示為解答 hahabala 2009年5月4日 上午 02:26
    2009年5月4日 上午 12:36

所有回覆

  • 不知道你要做什麼?
    用這個Context.DeleteObject(child物件)才能將資料存儲層的資料刪除.
    如果只將程式層的資料刪除,就將child 設 null 就好了.
    2009年4月30日 上午 08:16
  • hi..
    我想我有點詞不達意

    簡而言之我是比較好奇ORM中的一些物件操作(EF算是第一個接觸的ORM)
    要刪除一個Child,以Child的角度來看,當然就是執行刪除的動作..(Context.DeleteObject)
    但如果是從Parent物件中操作,將Child從Parent中集合移除
    其中的意義應該是,該Child跟該Parent已無關連,還是該Child是需要被刪除的

    最近會遇到這個問題是要把EntityObject存在Session中
    在類似Step by Step步驟異動該Entity後
    最後在執行SaveChange
    因為就會思考若在這個過程中Child被Parent Remove掉後是否需刪除的問題

    有點類似這個討論串的問題
    http://social.msdn.microsoft.com/forums/en-US/adodotnetentityframework/thread/984d3c83-ffef-460e-848a-fb8cf993d6bc/

    2009年4月30日 下午 03:29
  • Entity Framework對於一對多的情況刪除子集合元素必須要手動.
    所以你的想法在EF中無法實現


    但我覺得這點做法其實比較好
    因為自動刪除功能在實做上會遇到很多問題(以前用NHibernate時最後都改用手動).

    至於原因你可以研究一下NHibernate中PO/PJ的問題,實際上ORM要支援這功能在邏輯上有些狀況會產生衝突狀況導致並不好用,所以在EF中改為由使用者自行決定.
    • 已標示為解答 hahabala 2009年5月4日 上午 02:26
    2009年5月4日 上午 12:36
  • Entity Framework對於一對多的情況刪除子集合元素必須要手動.
    所以你的想法在EF中無法實現


    但我覺得這點做法其實比較好
    因為自動刪除功能在實做上會遇到很多問題(以前用NHibernate時最後都改用手動).

    至於原因你可以研究一下NHibernate中PO/PJ的問題,實際上ORM要支援這功能在邏輯上有些狀況會產生衝突狀況導致並不好用,所以在EF中改為由使用者自行決定.

    hi..可否在請教一下
    若在N-Tier的架構下,若要刪除子集合元素的經驗分享?
    (N-Tier下要手動刪除子集合元素物件應該比較不容易)
    2009年5月4日 上午 02:32
  • 其實這個問題是OO在撰寫上該如何處理的問題.
    底下的Code為Sample,在N-tier中你可能要視情況來修改(這段程式碼PO了好多問題...)

    class TestDeleteTransaction
    {
    int _customerId;
    List<int> _employeeIds = new List<int>();
    
    public Transaction(int customerId)
    {
    this._customerId = customerId;
    }
    
    public void DeleteEmployee(int employeeId)
    {
    this.employeeIds.Add(employeeId);
    }
    
    
    public void Execute()
    {
    CommonContext context = new CommonContext();
    
    foreach(int empId in this._employeeIds)
    {
    EntityKey key = new EntityKey(context.DefaultContainerName + ".Employee", "Id", empId);
    object emp = null;
    context.TryGetObjectByKey(key, out emp);
    context.DeleteObject(emp);
    }
    
    key = new EntityKey(context.DefaultContainerName + ".Customer", "Id", this._customerId);
    object cus = null;
    context.TryGetObjectByKey(key, out cus);
    context.DeleteObject(cus);
    }
    
    
    }
    如果需要在Execute中還可以增加Transaction機制.
    簡單來說不論是新增修改或刪除其實不應該只看過對資料庫異動,而是一連串的動作

    對於N-tier中如果使用的是非連線狀態的服務,譬如WebService,則你必須將這些動作做成不同的Function來呼叫,而且必須自行處理狀態間的維護問題(譬如用Session),而此時要維護的不是context本身而應該是TestDeleteTransaction這個class.
    2009年5月4日 上午 02:47
  • hi..感謝回答

    目前的EF要處理N-Tier還真有點麻煩
    期待104後支援POCO的EF V2版本了....
    2009年5月4日 上午 03:33
  • 上述方式是用OO寫法來處理

    此外
    微軟有出ADO.Net DataService就是要解決此問題所衍生出的東西,我沒用過,但你可以試看看.
    簡單來說就是透過Proxy物件,讓Client如Server端般操作EF

    2009年5月4日 上午 03:36