LINQ to SQL中的UPDATE SELECT

时间:2010-01-04 00:28:33

标签: .net linq linq-to-sql

我正在编写一个多线程服务,用于处理状态为1(未处理)的进程。一旦它们被拾取,我需要将这些行的状态更改为2(表示正在进行中),以便另一个线程(在几秒钟内生成)不会拾取这些行进行处理。

对于选择,我会做这样的事情:

var jobs = from j in db.Jobs
           where j.Status == 1
           select j;

如何重写此行以更新行并同时选择它们?

4 个答案:

答案 0 :(得分:1)

使用transaction。有一些例子说明它是如何运作的here

答案 1 :(得分:1)

这是典型的队列模式,要正确有效地执行此操作,必须使用带输出的更新:

UPDATE TOP (...) table
SET status = 2
OUTPUT deleted.*
WHERE status = 1;

没有等效的Linq2Sql,对于这个特定的工作,你不应该使用Linq。只需创建一个存储过程并将其显式添加到数据上下文中,然后将返回的类型修改为Jobs。你不会使用事务,而不是任何其他结构,甚至接近使用带有OUTPUT的UPDATE的性能。

我还添加了一个TOP子句,这在队列模式中相当常见,每个读者只需要有限的工作量就可以承受负载峰值。

答案 2 :(得分:0)

由于许多线程可能互相踩踏,最简单的方法是设置为当前作业或线程ID的另一个字段:

update t set runner_id = ? where runner_id = 0
select * from t where runner_id = ?
(? = my thread or connection id)

或者您可以使用锁或事务锁定表并执行2次查询:选择,然后更新到处理

答案 3 :(得分:0)

选择后我会有一个foreach更新值,然后提交它们,然后继续执行程序的其余部分

foreach (Job j in jobs)
{
    j.Status = 0;
}
db.SubmitChanges()

然后你仍然有你的工作,数据库更新......