So, I am converting an older project to new code, and here are the entities (irrelevant data removed)...
public partial class Event
{
public Event()
{
RecurringEvents = new HashSet<RecurringEvent>();
}
public int EventId { get; set; }
public int ModuleID { get; set; }
public DateTime EventDate { get; set; }
public DateTime CreateDate { get; set; }
public bool IsActive { get; set; }
public bool IsRecurring { get; set; }
public virtual ICollection<RecurringEvent> RecurringEvents { get; set; }
}
public partial class RecurringEvent
{
public int RecurringEventID { get; set; }
public int EventID { get; set; }
public DateTime EventDate { get; set; }
public virtual Event Event { get; set; }
}
Basically, I need the following SQL statement rewritten in an EF query:
SELECT e.EventId, e.Title, e.Abstract, ISNULL(re.EventDate, e.EventDate) AS EventDate, e.CreateDate, e.EndDate, e.IsActive, re.RecurringEventID AS RecurringEventId
FROM Calendar.Events AS e LEFT OUTER JOIN
Calendar.RecurringEvents AS re ON e.EventId = re.EventID
WHERE (e.ModuleID = 3045) AND (e.IsActive = 1) AND (e.EventDate >= '2015-03-01') AND (e.EventDate < '2015-05-31') OR (re.EventDate >= '2015-03-01') AND (re.EventDate < '2015-05-31')
EDIT This is the current query I have come up with, but it's returning an INNER JOIN instead of a LEFT JOIN...
IEnumerable<EventView> toReturn = _context.Events
.Join(_context.RecurringEvents.DefaultIfEmpty(),
e => e.EventId,
re => re.EventID,
(e, re) => new {Event = e, RecurringEvent = re})
.Where(ere =>
ere.Event.ModuleID == moduleID &&
ere.Event.IsActive == true &&
((ere.Event.EventDate >= startMonth && ere.Event.EventDate < endMonth) ||
(ere.RecurringEvent.EventDate >= startMonth && ere.RecurringEvent.EventDate < endMonth)))
.Select(ere => new EventView()
{
EventId = ere.Event.EventId,
Title = ere.Event.Title,
Abstract = ere.Event.Abstract,
EventDate = ere.RecurringEvent.EventDate != null ? ere.RecurringEvent.EventDate : ere.Event.EventDate,
CreateDate = ere.Event.CreateDate,
EndDate = ere.Event.EndDate,
IsActive = ere.Event.IsActive,
RecurringEventID = ere.RecurringEvent.RecurringEventID
}).AsEnumerable();
Any help appreciated. Thanks!
Ah, the infamous LEFT OUTER JOIN
in LINQ...you need to use DefaultIfEmpty()
https://msdn.microsoft.com/en-us/library/bb397895.aspx
It's the only tricky part here
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.