C# LINQ左和右连接查询

C# LINQ左和右连接查询,c#,sql-server,linq,C#,Sql Server,Linq,这是我的sql查询,如何将此查询生成到LINQ中: SELECT TimeTable.StartTime, sum(Booking.Quantity) as Total FROM PromotionSlot RIGHT JOIN TimeTable ON PromotionSlot.StartHour = TimeTable.StartTime LEFT JOIN Booking ON PromotionSlot.ID = Booking.PromotionSlotID GRO

这是我的sql查询,如何将此查询生成到LINQ中:

SELECT 
    TimeTable.StartTime,
    sum(Booking.Quantity) as Total
FROM PromotionSlot
RIGHT JOIN TimeTable
ON PromotionSlot.StartHour = TimeTable.StartTime
LEFT JOIN Booking
ON PromotionSlot.ID = Booking.PromotionSlotID
GROUP BY TimeTable.StartTime
结果:

|StartTime    |Total|
---------------------
 9             NULL
 10            NULL
 11            2
 12            2
 13            NULL
 14            NULL
 15            NULL
 16            NULL
 17            NULL
 18            NULL
 19            NULL
 20            NULL
 21            NULL
这就是我所尝试的,我不确定linq的结构与我的SQL查询是否正确。但是我遇到了一个错误,关于
转换为值类型“Int32”失败,因为具体化的值为null。结果类型的泛型参数或查询必须使用可为空的类型。
请指导我,谢谢大家

var bookingdata = 
    (from ps in dc.PromotionSlots
     join t in dc.TimeTables on ps.StartHour equals t.StartTime into Ts
     join bo in dc.Bookings on ps.ID equals bo.PromotionSlotID into Bs
     from time in Ts.DefaultIfEmpty()                         
     from book in Bs.DefaultIfEmpty()
     group new {time,book} by time.StartTime into NewGroup
     select new dataView
     {
         StartTime = NewGroup.Key,
         numBookings = NewGroup.Select(a => a.book!=null? a.book.Quantity: 0).Sum()
     }).ToList();
这是我的
dataView
型号

public class dataView
{
    public int? StartTime { get; set; }
    public int? numBookings { get; set; }
}
更新:

将我的dataView模型中的
StartTime
更改为
int?
,这是使用
console.log()


我找到了上面的
console.log()
将显示此结果的原因。我试图将我的SQL查询
右连接时间表
更改为
左连接时间表
。返回的结果与我的LINQ的输出完全相同。

我认为您遇到的问题是,在即席查询结果中,任何列值都可以为null(例如,结果示例中的Total列具有混合值,int和null)。但C#不是那么宽松,空值不能填充到整数值中

我认为在您的
dataView
类型中,
numBookings
属性可能被设置为
int
,而C#中的
int
类型不可为空

我相信如果将其更改为可为null的int,例如:

public int? numBookings { get; set; }
那就可以纠正你的错误了。如果不是这样,那么以下方法可能有效:

但我不确定最后一个

更新

如果将LINQ查询更新为对两个联接使用左联接,会怎么样

var bookingdata = (
    from t in dc.TimeTables 
    join ps in dc.PromotionSlots on t.StartTime equals ps.StartHour into Ts
    from time in Ts.DefaultIfEmpty()
    join bo in dc.Bookings on time.ID equals bo.PromotionSlotID into Bs
    from book in Bs.DefaultIfEmpty()
    group new {time, book} by time.StartTime into NewGroup
    select new dataView
    {
        StartTime = NewGroup.Key,
        numBookings = NewGroup.Select(a => a.book!=null? a.book.Quantity: 0).Sum()
    }
).ToList();

这是否使结果与SQL查询更加一致?

Hi,@jwatts1980在我的
dataview
model
numbookings
中已经
int?
@J4X可以使用该类定义更新问题。@J4X我已经更新了我的答案。请注意,我在第二个示例中添加了
(a.book.Quantity??0)
a.book.Quantity
可能为空。我遇到了此错误
运算符“??”不能应用于“int”和“int”类型的操作数
@J4X好的。。。现在,您已经更新了答案,似乎错误不在numBookings部分,而是在StartTime部分。控制台日志显示您的一个开始时间似乎为空,这可能是引发错误的部分。当您将StartTime更新为
int?
时是否收到错误?只是好奇,是否有特殊原因导致您进行正确的连接?在我看来,这样做只是增加了混乱,而不是与LEFT JOIN保持一致,因为它们实际上是可互换的。@jwatts1980,因为我正在尝试不同的JOIN,发现这种方法正是我想要的。这就是为什么我使用这个,请检查我更新的问题,我发现在我的
LINQ
中,两个
JOIN
都是
左连接
,而不是
左连接
右连接Ok。多年来,我从SQL管理员那里得到的大多数建议都是,与其说是为了避免正确的连接,不如说是为了在查询中与其中一个保持一致。我看到左连接的使用频率要高得多。大多数人倾向于认为“我希望表X是主数据集,我只希望从表Y中获得与X匹配的数据”(它描述了左连接)。
numBookings = NewGroup.Select(a => a.book!=null ? (a.book.Quantity ?? 0): 0).Sum() ?? 0
var bookingdata = (
    from t in dc.TimeTables 
    join ps in dc.PromotionSlots on t.StartTime equals ps.StartHour into Ts
    from time in Ts.DefaultIfEmpty()
    join bo in dc.Bookings on time.ID equals bo.PromotionSlotID into Bs
    from book in Bs.DefaultIfEmpty()
    group new {time, book} by time.StartTime into NewGroup
    select new dataView
    {
        StartTime = NewGroup.Key,
        numBookings = NewGroup.Select(a => a.book!=null? a.book.Quantity: 0).Sum()
    }
).ToList();