【问题标题】:Linq - Equivalent to BETWEEN inside a Left JoinLinq - 相当于左连接内的 BETWEEN
【发布时间】:2011-08-17 13:16:16
【问题描述】:

我看过这个话题BETWEEN EQUIVALENT in LINQ

我在 SQL 中的原始查询:

SELECT ISNULL(Tcar.name, '') FROM dbo.models model
LEFT JOIN cars Tcar on Tcar.model = model.id AND
                     Tcar.year between model.Start and model.End

我需要在“左连接”之间实现,我试过这个:

我的课程:

public class car
{
    public string name { get; set; }
    public int model { get; set; }
    public DateTime year { get; set; }
}

public class model
{
    public int id { get; set; }
    public DateTime Start { get; set; }
    public DateTime End { get; set; }
}

我的实现:

var theModel = from model in models
               join Tcar in cars
                    on new
                        {
                            ID = (int)model.id,
                            DateStart = (DateTime)model.Start,
                            DateEnd = (DateTime)model.End
                        }
                     equals new                                 
                         {
                             ID = (int)Tcar.model,
                             DateStart = (DateTime)Tcar.year,
                             DateEnd = (DateTime)Tcar.year
                         } into tempCar
                       from finalCar in tempCar
               select new
                   {
                       CAR = (finalCar == null ? String.Empty : finalCar.name)
                   };

解决方法:

var theModel = from model in models
               join Tcar in cars
                    on model.id equals Tcar.model
                where model.Start <= Tcar.year && model.End >= Tcar.year
               select new
                   {
                       CAR = Tcar.name
                   };

如果我使用解决方法 Linq 转换为该查询:

SELECT Tcar.name FROM dbo.models model
LEFT JOIN cars Tcar on Tcar.model == model.id
WHERE model.Start <= Tcar.year and model.End >= Tcar.year

我可以在“select new”之前放一个简单的where,但我必须通过这种方式实现,在左连接中使用“between”,我该怎么做?

【问题讨论】:

标签: c# linq


【解决方案1】:

编辑 - 添加 DefaultOrEmpty() 以使其成为左连接

像这样修改您的查询,这将强制 where 子句进入 join on 子句。它不会在 Join 中给你 Between 子句,但至少不会有 where 子句

var theModel = from model in models
               from Tcar in cars.Where(x => model.id == x.model)
                                .Where(x => model.Start <= x.year && model.End >= x.year)
                                .DefaultOrEmpty()
               select new
                   {
                       CAR = Tcar.name
                   };

【讨论】:

  • 我必须使用 Join 因为我需要检查左连接表是否有值。但是 Linq 没有这个实现 :(
  • @Gandarez - 这被翻译成加入
  • @Jon Skeet - 我使用了 Gandarez 在他的示例中使用的相同匿名类型。我觉得使用带有多个 Where 语句的双 from 以及最后的 DefaultOrEmpty 是在 Linq 中编写左连接的最易读的方式。并且生成的 sql 将连接条件放在 ON 中,而不是放在 Where 语句中
  • @Aducci:哦,对于 left 加入,这绝对正确。忽略我的 cmets,我错过了 OP 需要左连接。
  • 只将select子句改为-> CAR = (Tcar == null ? String.Empty : (string)Tcar.name)
【解决方案2】:

SQL Server 应该认为您的原始查询和 LINQ 生成的示例是相同的,因为 WHERE model.Start &lt;= Tcar.year and model.End &gt;= Tcar.yearON Tcar.year between model.Start and model.End 都指定了连接条件。

通常首选使用ON,因为它使您的连接条件与您的其他搜索条件分开,但这是为了可读性而不是性能。在我周围的几个表上测试类似的查询会产生相同的查询计划,如果您看到针对您的表的不同计划,我会感到惊讶。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-06
    • 2014-06-05
    • 1970-01-01
    • 1970-01-01
    • 2015-06-20
    • 1970-01-01
    • 2014-09-02
    • 1970-01-01
    相关资源
    最近更新 更多