1

我正在尝试实现自定义任务调度程序系统。我有以下(简化的)实体模型:

class User
{
    public virtual long UserId { get; set; }
    public virtual string Name { get; set; }
}

class Task
{
    public virtual long TaskId { get; set; }
    public virtual long? UserId { get; set; }
    public virtual string TaskName { get; set; }
    public virtual Guid SchedulerSessionUid { get; set; }
}

目前,对应的 SQL 表是直接的,其字段映射与它们在上面的类中出现的完全一样。

调度程序是一个 C# Windows 控制台应用程序。它将每天运行一次。它应该以以下方式工作(简化):

  1. 为当前会话生成 Guid
  2. 尝试选择下一个用户实体,该实体尚未在当前调度程序会话中安排任务(Guid 比较);如果没有找到这样的用户,请转到步骤 5。
  3. 为步骤 2 中选择的用户添加新任务。
  4. 转到第 2 步。
  5. 退出应用程序

这似乎是一个非常微不足道的问题,但我在执行第二步时遇到了问题。我尝试了各种查询,但有些规则总是阻止我。

以下是我在执行步骤 1 时必须遵守的一些规则:

  • 我不允许修改用户类或用户 SQL 表
  • 我可能会修改任务类和表,如果它有助于解决问题
  • 如果有帮助,我可能会添加一个新表或存储过程
  • 我必须以尽可能与 NHibernate 和 LINQ 兼容的方式实现它
  • 可能还存在一些与任何用户对象无关的任务(调度程序将忽略这些,但在设计 SQL/LINQ 查询和 NHibernate 映射时我仍然必须牢记这一点)。

这是一些真实世界的示例,它应该如何工作。

Users
-----------------
UserId    Name
-----------------
1         First
2         Second


Tasks
--------------------------------------------------------
TaskId    UserId    SchedulerSessionUid 
--------------------------------------------------------
1         NULL      6d8e48d0-4e92-477e-82fa-cd957e7dc201    
2         1         d213cfc8-23d6-49fb-b4e3-9ff3b60af6c4
3         1         9ee042df-88a7-447e-adbd-e7551ed50ae5

1.现在当Scheduler运行时,它会生成一个当前会话id = 76ea57fa-8c89-4c05-9ca2-a450b1f8a032。

  1. 现在它应该向 NHibernate LINQ 提供程序发出神奇的 LINQ 查询以获取用户实体
  2. 在第一次迭代中,查询应该返回 UserId=1 的用户实体,因为当前会话中还没有该用户的任务
  3. 现在调度器创建一个新任务,UserId=1,SchedulerSessionUid=76ea57fa-8c89-4c05-9ca2-a450b1f8a032。

在下一次迭代中,调度程序应该得到一个 UserId=2 的用户。再次插入一个新任务,UserId=2,SchedulerSessionUid=76ea57fa-8c89-4c05-9ca2-a450b1f8a03。在下一次迭代中,调度程序应该没有用户,所以它退出。

我可以使用什么 LINQ 查询来获取第 2 步的用户?我需要对我的 SQL 架构和实体模型进行哪些更改?

4

1 回答 1

1

如果我现在正确地关注您,您需要获取一个(只有一个)用户,该用户没有具有给定会话 ID 的任务。我对么?

Users.Where(u => !Tasks.Any(t = > t.UserId == u.UserId && t.SchedulerSessionUid == curSession)).FirstOrDefault()

编辑:

由于您正在为此进行多次旋转,因此您可能会更快地执行以下操作:

foreach(var user toDealWith Users.Where(u => !Tasks.Any(t = > t.UserId == u.UserId && t.SchedulerSessionUid == curSession)))
{
  //do stuff
}

而不是每次都访问数据库?

于 2012-08-27T19:11:21.567 回答