【问题标题】:Convert SQL statement to Linq Statement (3 table left joins + where)将 SQL 语句转换为 Linq 语句(3 个表左连接 + where)
【发布时间】:2015-02-15 14:49:57
【问题描述】:

这是我需要转换为 Linq 的工作 sql:

select * from dbo.Pod p
 left join dbo.PodEvent pe on p.PodId = pe.Pod_PodId
 left join dbo.Event e on pe.Event_EventId = e.EventId
where e.StartDateTime >= '2014-12-24 09:00:00.000' 
  and e.EndDateTime <= '2014-12-24 14:30:00.000'

我整天都在尝试来自不同帖子的建议,这是我能做的最好的事情,问题是它是一个内部连接,我需要它是一个左连接,这样我就可以在给定的时间内获取所有的豆荚间隔:

List<Pod> pods =
    (from p in db.Pods
     join pe in db.PodEvents on p.PodId equals pe.Pod.PodId
     join e in db.Events on pe.Event.EventId equals e.EventId
     where
     e.StartDateTime == userInfo.StartDateTime
      &&
     e.EndDateTime <= userInfo.EndDateTime
     select p).ToList();

谢谢

【问题讨论】:

标签: sql linq entity-framework left-join where-clause


【解决方案1】:

鉴于您的 SQL 中的 WHERE 过滤器将有效地呈现左外连接冗余,因为任何失败的连接都将是 filtered out by the WHERE clause,您可以使用这个事实通过连接表手动投影一个内连接,而无需导航(而且性能可能很糟糕):

var pods = db.Events.Where(e => e.StartDateTime >= userInfo.StartDateTime
                                 && e.EndDateTime < userInfo.EndDateTime)
                     .Join(db.PodEvents, 
                            e => e.EventID, 
                            pe => pe.EventId,
                            new (e, pe) => {
                               Event = e,
                               PodEvent = pe,
                               Pod = db.Pods.Single(p => p.PodId == pe.PodID)
                            })
                      .SelectMany(x => x.Pod);

但是,鉴于您可以通过 pe.Event.EventId 导航,为什么不修复所有三个表的导航,这样可以更简单:

var pods = db.Events.Where(e => e.StartDateTime >= userInfo.StartDateTime
                                && e.EndDateTime < userInfo.EndDateTime)
                    .SelectMany(e => e.PodEvents.Select(pe => pe.Pod));

此外,如果 PodEvent 只是一个连接表 (EventId, PodId) - 通过在 EF 中将其建模为 Many:Many,您可以完全避免 PodEvent 连接实体,EventPod 将变得可直接导航。

【讨论】:

  • 非常感谢您提供如此详细的回答!我有能力将我的连接表转换为 many::many 关系,我会的。你提到了一个导航问题,知道我该如何解决它吗?还是删除联结表可以解决问题?
  • 在 Sql 中,您必须拥有联结表,但在 EF 中,只要您只需要表中的 N:N 键,您就可以像不可见一样浏览它 - 请参阅 stackoverflow.com/a/5418534/314291stackoverflow.com/questions/21954520/…
  • 请原谅我的无知。你的意思是如果我通过 EF 做所有事情(我就是这样),那么我不需要我的连接表吗?或者我需要 sql 端的联结表,但我可以让 EF 认为它不存在?
  • 假设代码优先,这将在Sql中创建一个N:N联结表,并将关系通知EF:stackoverflow.com/a/26638150/314291
猜你喜欢
  • 2016-03-29
  • 1970-01-01
  • 1970-01-01
  • 2013-02-15
  • 1970-01-01
  • 2023-03-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多