2009-12-11 67 views
2

我想使用附加方法來更新通過存儲過程檢索的實體。使用連接與Linq到Sql和存儲過程

存儲過程設置爲返回一個特定的實例,它存在於我的dbml中。檢索按預期工作並返回一個完全填充的對象。我需要使用存儲過程的原因是我需要在檢索該實體的同時更新該實體的屬性。

當我檢索到這個實體後,我使用AutoMapper將它映射到另一個應用程序層使用的另一個模型。該層執行一些操作,並對實體進行更改,並將其傳回存儲庫進行更新。

存儲庫將此業務模型轉換回數據庫模型,並嘗試將其附加到datacontext以便利用automagic更新。

無論Attach(entity,true)Attach(entity)等是什麼組合,它都會給我提供諸如「找不到或更改的行」或「無法添加具有相同主鍵的實體」之類的消息。

有沒有人有任何關於Attach方法的經驗,以及如何使用查詢語法來更新不一定來自數據上下文的實體(即在這種情況下是存儲過程)?

非常感謝

回答

0

1:這是相同的數據上下文,並 2:這是同一個實體實例(或一個看起來像)

這隻會發生在相同的數據我懷疑這種情況。如果它是同一個實體,那麼它已經在那裏;只需撥打SumbitChanges即可。否則,請使用第二個數據上下文或分離原始實體。

0

因此,如果我通過存儲過程檢索實體,它是否被datacontext跟蹤?

事情是..我要從數據模型轉到另一個組件使用的另一個模型,然後返回。它不是..真的是同一個實例,但它具有所有相同的屬性。

IE

public Models.Tag GetEntity() 
      { 
       var dbTag = db.PROJ_GetEntity((int)EntityStatuses.Created, (int)EntityStatuses.CreatingInApi).SingleOrDefault(); 
       return FromDb Entity(dbEntity); 
      } 


var appModel = GetEntity(); // gets an Entity from a stored proc (NOT GetEntity_RESULT) 

appModel.MakeSomeChanges(); 

_Repo.Persist(appModel); 

public void Persist(Models.AppModel model) 
{ 
var dbEntity = Mapper.Map(model); 
db.Attach(dbEntity); 
db.SubmitChanges(); 
} 

這有點僞代碼一樣..但它演示功能相當多,我做什麼。

感謝

1

首先,如果你正在創建的對象的副本,進行更改,然後試圖複製的對象連接到相同的DataContext作爲一個在它原來的對象,那麼這可能會導致在「無法添加具有相同主鍵的實體」消息中。處理此問題的一種方法是: 1.從DataContext獲取對象 2.進行更改和映射對象(反之亦然 - 無論順序如何) 3.使用在其他層中創建的新值更新原始對象 4。包含原始對象上的DataContext的SubmitChanges

  1. 獲取從一個DataContext對象和關閉的DataContext
  2. 進行更改,然後做你的映射
  3. 從DataContext的檢索對象,該對象您要保存
  4. 使用映射對象中的值更新該對象
  5. SubmitChanges

或者,當你說你正在使用proc,因爲你需要在檢索它的同時更新一個屬性,我需要看到proc,但是如果你在檢索後以某種方式提交了這個更新信息,那麼確實消息「行未找到或改變」是正確的。這很難做到,但是如果您將數據加載到臨時表中,執行更新,然後使用臨時表中的選擇來填充對象,則可以執行此操作。您可以嘗試的一件事是在L2S設計器中將該屬性設置爲AutoUpdate = Never,並查看是否會導致問題消失。如果是這樣,這是你的問題。

0

我正在upvoting weenet的答案,因爲他是正確的 - 你不能使用附加應用更改。

與實體框架不同,只能將L2S對象附加到datacontext(如果它以前從未附加過) - 即它是您要插入到表中的新實體。

這確實會在多層環境中造成許多問題 - 但是通過創建一個使用反射和表達式樹的通用實體同步系統,我能夠解決許多問題。

對象被修改之後,我對DC和修改的對象中的新對象運行動態委託,以便在生成Update語句之前僅在DC中跟蹤差異。不過,對相關實體有點棘手。