【问题标题】:LINQ equivalent of this subselect此子选择的 LINQ 等效项
【发布时间】:2021-05-14 14:41:41
【问题描述】:

“任务”表:

public class Task
{
    public int ID { get; set; }
    public string name { get; set; }
}

“任务历史”表:

public class TaskHistory
{
    public Guid ID { get; set; }
    public DateTime Created { get; set; }
    public DateTime LastModified { get; set; }
    public string CreatedBy { get; set; }
    public int TaskID { get; set; }
    public TaskStatus { get; set; }
}

Sql 查询:最近 30 天内完成了哪些任务?

select * from Tasks 
where TaskStatus in ('Completed', 'Rejected')
and ID in (
    select distinct TaskID 
    from TaskHistory 
    where LastModified >= DateAdd(day, -30, GETDATE())
)

问:这个 SQL 查询的等效 LINQ 表达式是什么?

【问题讨论】:

  • 为什么你的类没有导航属性? 不可能在没有看到具有 FK 关系的 实际 EF 实体类型的情况下提议替换该 SQL 的 Linq 查询。
  • 当你的 SQL 只查询 Tasks 表时,TaskHistory 是什么意思?我对你的问题投了反对票,因为你显然没有花太多时间思考你提出的问题——这对于像你这样拥有 10k+ 业力的人来说是不合时宜的。你现在应该知道如何就 SO 提出一个好的问题了。
  • 我猜SQL子查询应该来自表TaskHistory,而不是Task
  • 1) 子选择中的错字:应该是“TaskHistory”。 2)我的理解是“导航”意味着a)上下文.cs中的额外代码,以及b)将外键约束引入数据库模式。 "b)" 会破坏交易...

标签: sql sql-server entity-framework linq entity-framework-core


【解决方案1】:

这个查询应该做你想做的:

var statuses = new [] {"Completed", "Rejected"};

var query = 
   from t in ctx.Tasks
   where statuses.Contains(t.TaskStatus)
      && ctx.TaskHistory
         .Any(th => th.LastModified <= DateTime.Now.AddDays(-30)
             && th.TaskID == t.ID)
   select t;
 

【讨论】:

  • @FoggyDay - 分析一下这个答案,因为它确实看起来效率很低。
  • 是的,我同意。原始查询也应该被分析。
  • @Svyatoslav Danyliv - 再次感谢您。我不确定是什么吓坏了所有人:1)我的错字(“来自 Task”而不是“来自 TaskHistory” - 已更正),2)我没有包含 EF 上下文(它是最小的 - 只有类是相关的), 3) 我故意选择 NOT 来使用 EF 导航或 4) 完全不同的东西。无论如何 - 你的解决方案很棒!
  • 他们的cmets是正确的。我只看到了查询的主要思想,我知道该怎么做。
【解决方案2】:

除非我遗漏了什么,否则我认为您的查询是这样做的:

IEnumerable<Task> query =
    from t in tasks
    join th in taskHistory on t.ID equals th.TaskID into ths
    where
        ths
            .Where(x => x.LastModified < DateTime.Now.AddDays(-30.0))
            .Any(x => new []
            {
                TaskStatus.Completed,
                TaskStatus.Rejected,
            }
            .Contains(x.TaskStatus)
    select t;

这很奇怪。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-06
    • 1970-01-01
    相关资源
    最近更新 更多