你如何使用linq中的“date between”运算符离开加入?

时间:2011-12-14 17:50:01

标签: .net sql linq

我有两张桌子。父表具有单个日期列,子表具有2个日期列(From / To)。我需要从父级到子级进行左连接,其中父级的日期列在子级中的一个之间。在sql中,这看起来像这样:

select p.cob, count(*) from parent p
left join child c on p.cob between c.effective and c.expiry
group by p.cob

如何在linq中写这个 - 我有点卡在这里......

4 个答案:

答案 0 :(得分:4)

这应该是你要找的东西

var query = from p in context.Parent
            from c in context.Child.Where(x => p.cob >= x.effective)
                                   .Where(x => p.cob <= x.expiry)
                                   .DefaultIfEmpty()
            group p by p.cob into pg
            select new
            {
              cob = pg.Key,
              count = pg.Count()
            };

答案 1 :(得分:1)

旧但也许对其他人有帮助。它使我的查询在特定数量的测试数据上快了7倍!

我有(28秒)

from st in subtable
join t in table on st.IdTable equals t.Id
Where t.date >= myStartDate
&& t.date <= myEndDate
&& st == some_other_conditions
select st

我把它改成了这个(4秒)

from st in subtable
join t in table on new { parent = st.IdTable, from = 1, to = 1 } equals new { parent = t.Id, from = (t.date >= myStartDate ? 1 :  0), to = (t.date <= myEndDate ? 1 : 0 )
Where st == some_other_conditions
select st

它在创建连接结果后检查其他条件,因此所有其余条件都适用于较少量的数据。

希望有所帮助

答案 2 :(得分:0)

如果我正确地阅读了您的问题,部分之间的就会像这样处理。

where p.cob >= c.effective and p.cob <= c.expiry

答案 3 :(得分:0)

  

我需要从父母到孩子进行左连接

在SQL中总是有多种表达需求的方式,我确信linq也是如此。

SELECT p.cob, COUNT(*) 
  FROM parent p
 WHERE EXISTS (
               SELECT * 
                 FROM child c 
                WHERE p.cob BETWEEN c.effective AND c.expiry
              )
 GROUP 
    BY p.cob
UNION
SELECT p.cob, 0 
  FROM parent p
 WHERE NOT EXISTS (
                   SELECT * 
                     FROM child c 
                    WHERE p.cob BETWEEN c.effective AND c.expiry
                  );

一个好的优化器会发现重复的派生表,两个联合表是互斥的,等等。