Выберите из таблицы, используя столбец XML - PullRequest
0 голосов
/ 18 ноября 2010

Я создаю планировщик задач в SQL Server 2008.
У меня есть таблица, которую я использую для хранения задач.Каждая задача - это имя задачи (например, ImportFile) и аргументы.Я храню аргументы в столбце 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)

Какие-либо альтернативные предложения по реализации?

Ответы [ 3 ]

1 голос
/ 20 ноября 2010

Это может быть растяжка, но вы можете использовать «хэш-код» при сохранении данных в базе данных, а затем запросить значение хэш-кода в более позднюю дату / время.

Это предполагает, что у вас есть класс, который представляет вашу задачу, и что вы переопределили метод 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.

1 голос
/ 18 ноября 2010

Возможно, вы захотите всплыть, например, строковое свойство, которое инкапсулирует ваш Arguments, или может быть достаточно иметь, например, длину и CRC вашего Arguments в качестве дополнительных свойств вашего класса:

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 голосов
/ 18 ноября 2010

Вы можете написать класс, который реализует 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...