2010-11-18 15 views
0

Ich erstellen einen Task-Scheduler auf SQL Server 2008.
Ich habe eine Tabelle, die ich zum Speichern von Aufgaben verwenden. Jede Aufgabe ist ein Aufgabenname (z. B. ImportFile) und Argumente. Ich speichere Argumente in der XML-Spalte, da verschiedene Aufgaben unterschiedliche Signaturen haben.Wählen Sie aus Tabelle mit XML-Spalte

Tabelle ist wie folgt:
Id:integer(PK) | operation:nvarchar | Arguments:xml

Bevor Sie eine Aufgabe Queuing, ich brauche oft hat, dass bestimmte Aufgabe zu überprüfen, noch nicht geplant. Das Nachschlagen erfolgt sowohl auf der Grundlage von Operationen als auch von Argumenten.

Frage: Verwenden von Linq-zu-Sql wie kann ich überprüfen, ob die angegebene Operation + Args in der Warteschlange bereits vorhanden ist?

Ich suche so etwas wie:

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

(das funktioniert nicht, da SQL Server nicht XML-Typ vergleichen kann)

Vorschläge

jede alternative Implementierung?

Antwort

1

Sie möchten z. eine Zeichenfolgeneigenschaft, die Ihre Arguments einkapselt, oder vielleicht wäre es ausreichend, z. die Länge und eine CRC Ihrer Arguments als zusätzliche Eigenschaften auf Ihrer Klasse:

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

    public int ArgumentCRC 
    { .... } 
} 

auf diese Weise, wenn Sie Länge (Ihrer XML) vergleichen und die CRC und sie übereinstimmen, können Sie ziemlich sicher und sicher bewegt werden Angenommen, die zwei XML-Dateien sind identisch. Ihr Scheck wäre dann etwa so:

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

oder so ähnlich.

+0

Ja, zumutbar. Aber ich habe ein Problem mit * ziemlich sicher * Teil. Ich habe gehofft, dass es eine bessere Lösung gibt.Eine Variante dieses Ansatzes ist die Verwendung von CRC, um die Ergebnisuntermenge signifikant einzugrenzen und dann (wenn mehr als ein Ergebnis zurückgegeben wird) einen (teuren) XML-Vergleich durchzuführen. –

0

Sie können eine Klasse schreiben, die IComparable implementiert:

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

Dies ist eine Strecke sein, aber Sie könnten eine „Hashcode“ verwenden, wenn die Daten in der Datenbank zu speichern, dann abfragen, auf dem Hash-Code-Wert bei einem späteres Datum/Uhrzeit.

Dies setzt voraus, dass Sie über eine Klasse verfügen, die Ihre Aufgabenentität darstellt, und dass Sie die GetHashCode-Methode der Klasse überschrieben haben.

Wenn Sie jetzt die Datenbank abfragen, um zu sehen, ob sich die Aufgabe in der geplanten Warteschlange befindet, fragen Sie einfach nach dem Hashcode ab und vermeiden so, dass jede XML-Datei zur Abfragezeit stochern muss.

var t1 = neue Aufgabe {Operation = "Ausführen", Argumente = "someXElement.value"}; var t2 = neue Aufgabe {Operation = "Ausführen", Argumente = "someXElement.value"};

im Code über t1 == t2, weil Sie GetHashCode überschreiben und den Hash für Operation + Arguments.Value berechnen. Wenn Sie den Hashcode in der db speichern, können Sie leicht feststellen, ob Sie ein Objekt im DB haben, das dem Hash-Code entspricht, nach dem Sie suchen.

Dies kann ähnlich sein, worüber marc_s sprach.

Verwandte Themen