使用XML列从表中选择

时间:2010-11-18 18:10:02

标签: sql-server xml linq-to-sql

我正在SQL Server 2008上创建一个任务调度程序 我有一个用于存储任务的表。每个任务都是一个任务名称(例如ImportFile)和参数。我将参数存储在XML列中,因为不同的任务具有不同的签名。

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

在排队任务之前,我经常需要验证还没有安排给定的任务。查找是基于operation和args完成的。

问题:使用Linq-to-Sql如何检查队列中是否存在给定的操作+ args?

我正在寻找类似的东西:

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

(由于SQL Server无法比较XML类型,因此无效)

任何其他实施建议?

3 个答案:

答案 0 :(得分: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);

或类似的东西。

答案 1 :(得分:1)

这可能是一个延伸,但您可以在将数据保存到数据库时使用“Hashcode”,然后在以后的日期/时间查询哈希码值。

这假设您有一个代表您的任务实体的类,并且您已经覆盖了所述类的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所说的。

答案 2 :(得分: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);