【问题标题】:EF Linq Select and Update or vise versa in one stepEF Linq 一步完成选择和更新,反之亦然
【发布时间】:2015-01-08 08:21:30
【问题描述】:

我有多个异步 Windows 服务的情况。 所有人都在使用一张“工作”表。假设有两列:“Id”和“Loaded”

此表中有 50 个职位。
我现在想要的是,这项服务每次只抓取 10 个工作并对其进行处理。

但是一个工作不会被处理两次是非常重要的。 服务仅捕获“已加载”为空的作业。

如果现在“服务 A”来并加载前 10 个“已加载”为空的作业,则可能需要 5 秒。 在这 5 秒内。 “服务 B”来了,也加载了 10 个工作,这个工作是一样的。 (危险!)

为了避免重复处理的作业,我现在要做的是在一个语句中加载 10 个作业并更新它们(“加载”为 DateTime.UtcNow),或者在一个语句中更新它们并加载受影响的。

但我不知道这是否可能。 有人可以帮我吗?

亲切的问候

【问题讨论】:

  • 最简单的解决方案是“告诉”您的 Windows 服务要执行哪些作业,例如通过在您的表中添加一个表示每个 win 服务的虚拟 id 的附加列,然后每个服务将只接受那些拥有自己 ID 的作业。
  • 这是不切实际的,因为理论上它可能是相同的服务,因为就像我说的它们是异步的。第二个原因是,我想学点东西;)
  • 这是不切实际的,因为理论上它可能是相同的服务,因为就像我说的它们是异步的。如果“服务 A”异步抓取 10 个作业及其 id,这需要 5 秒。然后在这 5 秒内。 “服务 A”异步再次获取 10 个带有其 id 的作业,这 10 个作业也相同。第二个原因是,我想学点东西;)

标签: c# linq entity-framework ef-code-first


【解决方案1】:

我认为你可以这样做

   list.Where(j => j.Loaded == null).Take(10).AsEnumerable()
                .Select(x =>
                {
                    x.Loaded = DateTime.UtcNow;
                    db.SaveChanges();
                    return x;
                })
                .ToList().ForEach(j => //proccess job here);

【讨论】:

  • 不幸的是:语法错误“无法将带有语句体的 lambda 表达式转换为表达式树。
  • 否,因为 Loaded 是一个 DateTime 列
  • 现在和以前一样,只是格式不同。我不认为这是正确的方法。 (我希望是这样!)
  • 我仍然收到语法错误“无法将带有语句体的 lambda 表达式转换为表达式树。”
  • 问题是,你做的是 Linq2Objects 而不是 Linq2Sql!
【解决方案2】:

您遇到并发数据库访问问题。您的目的是更新使用标志读取的每个作业,以便不会再次处理它。想到了两个想法:

  • 独家数据库访问 您将只允许一个 Windows 服务读取和更新它一次读取的记录。这将确保不会重复处理任何作业。
  • 读取所有项目 每次读取所有可用作业,然后将它们分发到每个 Windows 服务。您必须在读取作业的应用程序和 Windows 服务之间实现某种形式的数据共享。这个想法使您可以更好地控制每个服务处理的作业。

【讨论】:

  • 那么,TransactionScope 之类的东西不可能吗?
  • 这些只是我想出来的想法,当然可能还有更多,TransactionScope就是其中之一:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-05
  • 2020-05-04
  • 1970-01-01
  • 2014-07-17
  • 2015-03-02
  • 1970-01-01
  • 2011-06-15
相关资源
最近更新 更多