[Linq2Sql]跟Hibernate真的差很多

[Linq2Sql]跟Hibernate真的差很多

前幾天的一篇: [Linq2Sql]刪除後重新排列的異象 ?

今天再測了一個CASE

先用InsertOnSubmit父資料(PRJ).

再用ExecuteCommand加入子資料(GRP).

   1:  this.context.PRJ.InsertOnSubmit(new PRJ() { ENABLE_FLAG = 'N', PRJ_ID = 999, PRJ_DESC = "999", PRJ_NAME = "999" });
   2:  int rtnVal = this.context.ExecuteCommand("INSERT INTO ADM.GRP (PRJ_ID,USR_NAME,GRP_NAME,AP_ID) ( SELECT PRJ_ID, 'dev' , 'DEV', 1 FROM ADM.PRJ WHERE PRJ_ID=999)");
   3:  this.context.SubmitChanges();

 

rtnVal = 0 , 表示子資料新增失敗了, 看一下執行的結果

 

   1:  INSERT INTO ADM.GRP (PRJ_ID,USR_NAME,GRP_NAME,AP_ID) ( SELECT PRJ_ID, 'dev' , 'DEV', 1 FROM ADM.PRJ WHERE PRJ_ID=999)
   2:  -- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.5420
   3:   
   4:  INSERT INTO [ADM].[PRJ]([PRJ_ID], [PRJ_NAME], [PRJ_DESC], [ENABLE_FLAG])
   5:  VALUES (@p0, @p1, @p2, @p3, @p4, @p5)
   6:  -- @p0: Input Int (Size = 0; Prec = 0; Scale = 0) [999]
   7:  -- @p1: Input VarChar (Size = 3; Prec = 0; Scale = 0) [999]
   8:  -- @p2: Input NVarChar (Size = 3; Prec = 0; Scale = 0) [999]
   9:  -- @p3: Input Char (Size = 1; Prec = 0; Scale = 0) [N]
  10:  -- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.5420

果然是 "InsertOnSubmit" , 就是要等你下 "SubmitChanges()" 才會一口氣全部執行.

而我因為中了Hibernate的毒太久, 所以天真的以為, 它有一層persist, 如果發現有差異就會自動flush 跟db 連動 ... (不好好讀書的下場, 憑感覺亂套feature …)

這造成了什麼事呢? 因為我切了一個 Layer "DAO" , 裡頭都是用 "InsertOnSubmit" 來實作 "add()",

而另一個 Layer "Service" 則引用 "DAO" , 結果在 add / select / add ... 等交叉使用時出現了一堆的蟲 ...

因為我預期的persist並不存在, 所以該存在的資料不存在, 該刪除的資料沒刪除 Orz ~

 

最後只好用上 "TransactionScope" 來幫忙, 將所有的 "DAO" 的方法都下 "SubmitChanges" , 然後最後再用 "Complete" 一併送出.

示意如下:

   1:              using (TransactionScope trans = new TransactionScope())
   2:              {                
   3:                  context.Log = Console.Out;
   4:                  this.context.PRJ.InsertOnSubmit(new PRJ() { ENABLE_FLAG = 'N', PRJ_ID = 999, PRJ_DESC = "999", PRJ_NAME = "999" });
   5:                  this.context.SubmitChanges();                
   6:                  rtnVal = this.context.ExecuteCommand("INSERT INTO ADM.GRP (PRJ_ID,USR_NAME,GRP_NAME,AP_ID) ( SELECT PRJ_ID, 'dev' , 'DEV', 1 FROM ADM.PRJ WHERE PRJ_ID=999)");
   7:                  trans.Complete();
   8:              }

rtnVal = 1 , 表示子資料新增成功了.

 

經驗真的是用錯誤來累積, 而錯誤來自己的自以為是 唉 (PS. 之前專案留下的BUG怎麼辦?! 驚恐中 ... )