2010-11-18 54 views
0

我正在SQL Server 2008上創建一個任務調度程序。
我有一張表,用於存儲任務。每個任務都是任務名稱(例如ImportFile)和參數。我將參數存儲在XML列中,因爲不同的任務具有不同的簽名。使用XML列從表中選擇

表如下:
Id:integer(PK) | operation:nvarchar | Arguments:xml

前排隊的任務時,我經常需要驗證給定的任務尚未安排。查找是基於操作和參數完成的。

問題:使用Linq-to-Sql如何檢查給定操作+ args是否已經存在於隊列中?

我要尋找類似:

var isTaskScheduled = db.Tasks.Any(t => 
    t.Opearation == task.Operation && 
    t.Arguments == task.ArgumentsAsXElement); 

任何替代實施意見(因爲SQL Server無法比擬的XML類型不工作)?

回答

1

您可能想要一個字符串屬性,用於封裝您的Arguments,或者它可能足以包含例如長度和你Arguments作爲額外的屬性對你的類CRC:

public partial class Task 
{ 
    public int ArgumentLength 
    { .... } 

    public int ArgumentCRC 
    { .... } 
} 

這樣,如果你可以比較長(你的XML)和CRC,並將它們匹配,你可以相當肯定,安全地假定兩個XML是相同的。您的支票然後會是這樣的:

var isTaskScheduled = 
    db.Tasks.Any(t => t.Operation == task.Operation && 
         t.ArgumentLength == task.ArgumentLength && 
         t.ArgumentCRC == task.ArgumentCRC); 

或類似的東西。

+0

是的,合理的。但是我有*非常確定*部分的問題。我希望有更好的解決方案。這種方法的一個變體是使用CRC來顯着縮小結果子集,然後(如果多於一個結果返回)做(昂貴的)XML比較。 – 2010-11-18 18:19:45

0

你可以寫一個實現IComparable的一類:

public class XMLArgument : IComparable 
{ 
    public XMLArgument(string argument) 
    { 

    } 

    public int CompareTo(object obj) 
    { 
     ... 
    } 
} 

var isTaskScheduled = db.Tasks.Any(t => 
    t.Opearation == task.Operation && 
    (new XMLArgument(t.Arguments)).CompareTo(new XMLArgument(task.ArgumentsAsXElement)) == 0); 
1

這可能是一個延伸,而是將數據保存到數據庫時,在一個你可以使用一個「雜湊碼」,然後查詢的哈希碼值以後的日期/時間。

這假定您有一個類表示您的任務實體,並且您已經重寫了該類的GetHashCode方法。

現在,當你去查詢數據庫,看看任務是在預定的隊列中,您只需在哈希碼進行查詢,從而避免了需要做任何XML查詢時戳。

var t1 = new Task {Operation =「Run」,Arguments =「someXElement.value」}; var t2 = new Task {Operation =「Run」,Arguments =「someXElement.value」};

在t1 == t2之上的代碼中,因爲您正在重寫GetHashCode並計算Operation + Arguments.Value的散列值。如果將散列碼存儲在數據庫中,那麼您可以輕鬆判斷數據庫中是否存在與您正在檢查的散列碼相同的對象。

這可能是類似於marc_s在說什麼。