2010-08-03 64 views
4

我通過LINQ將數據從數據庫提取到SQL,因此使用DataContext對象。數據定義何時執行某些操作,並且可以獨立於我的服務進行更新。LINQ to SQL - 確定我是否有陳舊的數據

我週期性地輪詢數據庫以查看計劃是否已更新並相應地調整我的計劃。

也就是說,如果我知道如何確定數據是否陳舊,我會。

  • 我需要創建的每個新的DataContext檢查
  • 我需要實現該行類型的定製平等法和遍歷表?

理想情況下,我會做另一個選擇使用相同的數據上下文,並獲得對錶的引用,然後調用Equals。我意識到我住在夢境中。

+0

夢想之地如何?...我一直在想到那裏。 – Rusty 2010-08-03 21:42:58

回答

2

好問題!

我發現過這個問題,如果有人想使用的SqlDependency與LINQ到SQL此博客條目...

http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2007/05/04/9302.aspx

,將攜手在手與this的WinForms的。 (您沒有指定的WinForms或ASP.NET)

編輯 - 添加

注意,這僅適用於客戶端應用程序(的WinForms等),那裏有客戶的一個非常小的數目,或與ASP.NET應用程序。在http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldependency.aspx MSDN文檔此其文檔中:

的SqlDependency被設計在ASP.NET或中間層服務 使用 那裏是一個相對較小的 數防範主動服務器具有依賴性 的數據庫。這是 不適用於客戶端 應用程序,其中數百或 成千上萬的客戶端計算機將 SqlDependency對象設置爲 單個數據庫服務器。

但是,如果你正在設計一個只有少數用戶的應用程序,這應該是可以接受的。

+1

爲什麼這是一個不好的答案?如果我可以向他們學習,我不介意低估... – David 2010-08-03 21:34:54

+0

這並不是一個不錯的答案。相反,StackOverflow是一個非常糟糕的網站:如果我等待太久,它不允許我收回投票。除非帖子被編輯。你做了哪些。所以我收回了downvote。 – Timwi 2010-08-03 21:50:04

+0

嗯,我正要推薦查詢通知,因爲我不記得班名 - 然後發現你已經提到過它。進一步閱讀:http://dunnry.com/blog/UsingSQLDependencyObjectsWithLINQ.aspx – 2010-08-05 02:25:33

0

DataContext派生的自動生成的類不打算是長壽命的對象。在絕大多數用例中,你應該實例化一個,讀取你需要的數據和/或進行你需要的改變,提交,然後忘掉這個對象。它不直接表示與數據庫的連接 - 實例化大量DataContext s不一定會打開到數據庫的多個連接。

這樣做的後果是你應該認爲你的數據是總是陳舊,特別是如果一個單獨的進程可以訪問同一個數據庫。只要您檢索到數據,其他進程就可以立即更新該數據。確保非陳舊性的唯一方法是維持一個開放的交易,而且我相信您知道,保持交易持續時間過長的後果是其他流程會發現數據庫非常無響應,就好像它非常慢 - 所以只使用事務處理步驟,幾乎只涉及需要原子化的數據​​庫訪問。

因此,在您的具體情況下,找出是否有任何新操作需要執行的唯一方法是不斷詢問數據庫。您不必一直檢索數據並使用Equals進行比較;您可以只檢索尚未得到的所有數據,即告訴數據庫僅返回新的行。因爲我不知道你的數據庫模式,我胡編這裏,但我敢肯定,這會給你一個想法:

var newActions = db.ScheduledActions.Where(act => !oldActions.Contains(act)).ToList(); 
if (newActions.Any()) { 
    // ... do something intelligent with the new actions ... 
    oldActions = oldActions.Concat(newActions); 
    // or perhaps oldActions.AddRange(newActions); if oldActions is a List<> 
} 

編輯:我現在認識到,你需要檢查不僅針對新的動作,還針對更改爲現有動作。就我個人而言,實現這一點的方法是在ScheduledActions表上指定一個日期/時間字段,用於指定上次更改的時間。那麼你不需要一個自定義的相等比較器,而是可以使用它來找出發生了什麼變化。不幸的是,這意味着你需要檢索所有的動作,甚至是那些沒有改變的動作。在下面的例子中,我假定ScheduledAction是由string類型的主鍵標識的;更改到int如果你使用數字鍵:

Dictionary<string, ScheduledAction> oldActions = new ...; 

[...] 

var allActions = db.Actions.ToList(); 
var changedActions = allActions.Where(act => !oldActions.ContainsKey(act.Id) || oldActions[act.Id].LastChanged < act.LastChanged).ToList(); 
if (changedActions.Any()) 
{ 
    // do something intelligent here 
} 
+0

你的db對象在這裏是什麼類型? – gav 2010-08-05 11:43:17

0

我有另外一個答案,這是從我第一次不同,但我仍然認爲首先是在有限的情況下有效的選項,所以我發帖這個分開。

你真正在談論的是處理LINQ的併發問題。微軟提供了指導在這裏:

http://msdn.microsoft.com/en-us/library/bb399373.aspx

0

首先,你需要非常clearely定義哪些數據(表,列(S))到底是受您的改變/更新手錶,到底發生了什麼的DB側當數據發生變化時。在你的情況下,「計劃已經更新」是什麼意思 - 單行中的一列會發生變化,但它不會影響優先級或影響增量變化的列。您是否將影響計劃的數據與僅影響處理的數據分開?

這些問題的答案批判地確定甚至原則上什麼是可行的。一般來說,沒有抽象的解決方案來解決問題。

一旦你確定什麼是什麼,什麼影響什麼和分離真正的調度數據(確定什麼時候被處理)從處理日期(確定如何處理),你會減少你的問題,只有兩點的變化和兩點反應。

然後,您可以使用sprocs和觸發器控制DB側的插入和更新,以便所有新事物都被標記爲這樣。然後你製作一個只詢問市場行並將它們標記爲「讀取」的sproc。當你的中層接收到它時,它會調用另一個sproc來承認,並且sproc標記它們已經過時。這種變化取決於實際架構,但這是關鍵 - 當場標記和更新數據的狀態 - 意思是SQL。如果沒有及時的確認(這意味着你的中層死亡),SQL還需要觸發器才能將記錄從「讀取」恢復爲「新的」。

根本就沒有DC的LINQ。 一旦你解決了這個問題,你確實可以做一個單一查詢的等價物,並只接收相對於以前的讀數而言是新的物品。

此外,您從LINQ收到的內容不是對任何形式的表格的引用 - 它是接收到的記錄的表示形式 - 只有當您的查詢不會拼出字段時,它們纔會看起來像表格記錄你真的需要。當你開始使用sporcs時,它會代表任何sproc的結果集 - 這可以是來自5個表的連接,但總共只選擇3個字段。