C# 如何在linq sql中实现对数据库记录的互斥

C# 如何在linq sql中实现对数据库记录的互斥,c#,.net,multithreading,linq-to-sql,C#,.net,Multithreading,Linq To Sql,我有一个分布式客户机-服务器系统,它有多个“工作者”引擎和一个WCF服务,我们称之为FileManagerService,它将“作业”添加到数据库中,以便“工作者”引擎拾取和处理 数据库由两个表组成:作业和文件。每个作业都在文件上运行(多对一关系)。可以一次将多个作业添加到作业表中,它们以队列的方式进行处理 作业的示例包括:MoveFile或DeleteFile等操作 我试图通过在文件表本身中使用“锁定”(bool)列,在文件记录上实现互斥 我认为所需的互斥区位于WCF服务FileManager

我有一个分布式客户机-服务器系统,它有多个“工作者”引擎和一个WCF服务,我们称之为
FileManagerService
,它将“作业”添加到数据库中,以便“工作者”引擎拾取和处理

数据库由两个表组成:
作业
文件
。每个作业都在
文件上运行(多对一关系)。可以一次将多个作业添加到
作业
表中,它们以队列的方式进行处理

作业
的示例包括:MoveFile或DeleteFile等操作

我试图通过在
文件
表本身中使用“锁定”(bool)列,在
文件
记录上实现互斥

我认为所需的互斥区位于WCF服务
FileManagerService
的方法:
addJob()
和“worker”引擎
TakeAndProcessAJob()

目前,我在解决LINQtoSQL延迟执行以及LINQtoSQL事务系统如何工作方面遇到了困难

我目前有以下方法,应该从
作业
表中获取
作业
,检查其相关
文件
是否已锁定,如果已锁定,我们将不返回任何内容,如果未锁定,我们将锁定
文件
并返回
作业
,并从
作业
队列中删除该
作业

public static Job GetAnAvailableJob()
{
    using (DBDataContext db = new DBDataContext())
    {
        DataLoadOptions loadOptions = new DataLoadOptions();
        loadOptions.LoadWith<Job>(f => f.File);
        db.LoadOptions = loadOptions;
        var jobAvailable = from ja in db.Jobs
                                    where ja.File.locked == false
                                    select ja;
        var jobToTake = jobAvailable.FirstOrDefault();
        // This file temp is here so that we can return
        // an associated File with the Job.
        // We delete
        File fileTemp = null;
        if (jobToTake != null)
        {
            fileTemp = jobToTake.File;
            jobAvailable.File.locked = true;
            Console.WriteLine("Locked file:" + fileTemp.FileID);
            db.Jobs.DeleteOnSubmit(jobToTake);
            db.SubmitChanges();
            jobToTake.Asset = fileTemp;
        }
        return jobToTake;
    }
}
我需要在这两种方法中更改什么,以使其以事务方式运行,并在
文件
记录上实现互斥。目前,我在
TakeAndProcessAJob()
方法中的
SubmitChanges()
上收到更改冲突异常-行未更改或未找到

谢谢,“行未更改或未找到”错误可能很简单,例如数据库模型文件与实际的物理数据库架构不匹配

另一个原因可能是LINQ没有检测到任何要提交的更改。假设您选择的记录已为真,并将其标记为真。您可以通过不更新来避免这种情况,如果它已经为真,或者原因可能是在表上该字段的属性下的模式文件上有一个设置,您可以实际关闭UpdateCheck,但听起来这不是您想要的

在一个无关的故事中:
当找不到与firstOrDefault()相关的内容时,“.Single()”是否会抛出一个错误,firstOrDefault()只返回null?

我想不出问题的答案,因此我进行了一些逻辑重组,并使用简单的旧SQL设计了一个解决方案。要锁定记录,我现在对记录使用单行(原子)命令:

updatedatatable SET locked='True'其中(locked='False')和(recordID=15)

然后我使用
SqlDataReader
并检查
recordsafected
字段。如果记录已更改,则表示我已成功锁定该记录。如果记录未更改,则表示该记录已被锁定,因此我在锁定方法中返回
false

试图锁定记录的进程随后位于while循环中,调用
lockRecord
并等待成功的回调

我不确定是否完全有必要从LINQ切换到SQL。我在应用程序中进行了逻辑更改,同时切换到计划SQL,因此很难确定使用LINQ是否是问题所在

public static bool LockAsset(long FileID)
{
    using (DBDataContext db = new DBDataContext())
    {
        var fileToLock = db.Files.Where(f => f.FileID == FileID && f.locked == false).Single();
        if (fileToLock == null)
        {
            return false;
        }
        else
        {
            Console.WriteLine("Locked File:" + fileToLock.AssetID);
            fileToLock.locked = true;
            db.SubmitChanges();
            return true;
        }
    }
}