Reputation: 119
This is my sql query, how can I generate this query into 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
Result:
|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
This is what I attempted, I'm not sure that the structure of the linq is correct with my SQL query. But I faced error about The cast to value type 'Int32' failed because the materialized value is null. Either the result type's generic parameter or the query must use a nullable type.
Please guide me, thank you all in advance!
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();
Here is my dataView
model
public class dataView
{
public int? StartTime { get; set; }
public int? numBookings { get; set; }
}
UPDATED:
changed StartTime
in my dataView model to int?
and this is the result by using console.log()
Format: @:console.log("* " + "@item.StartTime" + ":" + "@item.numBookings");
* :0
* 10:0
* 11:2
* 12:2
I found out the reason why the above console.log()
will appear this result. I tried to change my SQL Query RIGHT JOIN TimeTable
to LEFT JOIN TimeTable
. The return result totally the same like the output from my LINQ.
Upvotes: 1
Views: 2065
Reputation: 7356
I think the problem you're hitting is that in ad-hoc query results, any column value can be null (eg., the Total column in your results example has mixed values, int and null). But C# is not so lenient, an a null value cannot be stuffed into a integer value.
I think that in your dataView
type, the numBookings
property is probably set to int
, and an int
type in C# is not nullable.
I believe if you change it to a nullable int, like:
public int? numBookings { get; set; }
then that may fix your error. If not that, then the following might work:
numBookings = NewGroup.Select(a => a.book!=null ? (a.book.Quantity ?? 0): 0).Sum() ?? 0
But I am not sure about this last one.
UPDATE
What if you update your LINQ query to use LEFT JOIN for both joins, like so:
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();
Does this make the results more consistent with the SQL query?
Upvotes: 2