2012-04-15 23 views
1

根據此post,我使用每次調用的數據上下文,因此在我的WCF服務的每種方法中,我使用使用塊創建新的數據上下文。實體框架4.1:如何使用每個調用生命週期的數據上下文?

但我有一些懷疑在這種形式的工作。例如,我使用從我的存儲庫獲取數據庫的所有客戶端的方法getAllCLients(),然後將服務發送到調用該方法的客戶端,並將其與所有客戶端進行列表。然後用戶修改其中一些的信息,例如三個。修改客戶端也許我可以添加到具有修改客戶端的列表中。

當我想更新這三個客戶端時,我可以調用一個方法updateClients(),它接收修改後的客戶端列表。我如何使用每種方法的新數據上下文,在updateCients()中獲取新的dataContext,沒有實體,所以我認爲我必須按照以下步驟操作:

1.-創建一個新的數據上下文,我想要更新的客戶端。所以我需要爲此指定條件。這是一個額外的操作(我使用getAllClients()方法獲得客戶端),所以我需要再次獲取客戶端。

2.-拋出DBSet(我使用EF 4.1)的客戶端集合並更改信息。這使我去扔我從客戶端應用程序也收到的列表。所以我必須去扔兩個名單。這需要資源。

3.-保存更改。無論如何這是需要的,所以它不需要更多的工作。

有什麼辦法可以輕鬆完成第2步?在dataContext中存在一些方法將數據從我修改的客戶端傳遞到客戶端的數據上下文中?我使用POCO實體,也許它存在一個簡單的方法來做到這一點。

其他問題是關於併發性。如果我控制併發性並允許EF(例如帶時間戳字段),爲每個客戶端調用updateClient()還是更好地向所有客戶端傳遞列表最好?我的意思是,如果我使用列表作爲參數,如果有一個客戶端的併發問題,例如第二個,第一個客戶端將正確更新,但第二個不是和第三個都不是。我如何通知用戶有些客戶有問題?

要恢復,我想知道當我有一個短生命datacontext時進行更新的最佳方式。

謝謝。 Daimroc。

回答

4

服務處於斷開連接的情況,所以當您的客戶端傳回已修改的記錄時,您只需修改它們即可處理它們。您不需要爲數據庫加載所有記錄。

public void SaveClients(List<Client> modifiedClients) 
{ 
    using (var context = new Context()) 
    { 
     modifiedClients.ForEach(c => 
      { 
       context.Entry(c).State = EntityState.Modified; 
      }); 
     context.SaveChanges(); 
    } 
} 

如果你每次通話服務,每一個服務操作使用需求背景下,你可以將你的背景來實例化服務構造,因爲服務實例將只活到服務器的單一服務呼叫=你不需要using每次調用。如果你這樣做,不要忘記在你的服務上實現IDisposable來處理上下文。

其他問題是關於併發性。如果我使用 控制併發性並允許EF(例如 的時間戳字段)的併發性,爲每個客戶端 或更好的方式調用updateClient()函數更好地傳遞一個列表給所有客戶端更好嗎?

EF不支持開箱即用的併發性。使用時間戳是樂觀的併發性,因爲它允許其他人使用記錄。 Pesimistic併發是其他客戶端無法選擇鎖定記錄進行更新的應用程序邏輯。

每條記錄​​都解決了併發問題,但這種情況下的問題是事務。每次調用SaveChanges都會導致用於處理數據庫中所有更改的事務。因此,如果您的任何修改記錄不是最新的,您將收到併發異常,並且整個事務被回滾=沒有記錄被更新。

您仍然可以通過將修改記錄的列表傳遞給服務來解決此問題(減少客戶端和服務之間的往返是最佳實踐),但是您可以通過爲每條記錄調用SaveChanges來單獨處理每條記錄。無論如何,這應該是非常仔細的考慮,因爲每個電話SaveChanges就像是單獨的工作單位 - 它真的是你想要的嗎?

Btw。最好的做法是讓你的服務無狀態。你應該避免在服務調用之間維護數據,這個例子實際上並不需要它。

+0

那麼,我的想法是從調用中維護數據,這是因爲用戶具有訪問權限級別,並且我想僅向用戶發送用於該用戶的數據,所以我想知道一些數據如客戶端級別權限和回調。所以我認爲每次會議都是最好的選擇。我也想給你回電。在每次通話服務中是否可以使用雙面打印?謝謝。 – 2012-04-16 09:01:13

+0

沒有雙工場景需要會話。 – 2012-04-16 09:38:01

+0

我怎麼能知道我想撥打的客戶端(回叫)? 謝謝。 – 2012-04-16 09:47:52

相關問題