简体   繁体   中英

Entity Framework 6.1 query with two tables and a bunch of filters

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM