简体   繁体   中英

Conditional IF statement in LINQ statement

I have a SQL Database hosted in Azure along with my Web app (both in the same data center as well).

I have a few similar LINQ queries which basically differ only in the .Where() clause.

Since the queries are similar, I don't want to have to have code repition anywhere but I don't think LINQ allows me to have conditional IFs in the statements.

I've added a code snippet below, so any pointers on this would be helpful. I should also mention it's querying a View and not a table.

case Constants.OPENED:
    lstQueryEvents = db.tblEmailEvents
        .Where(t => t.strType.ToUpper() == Constants.OPENED_TYPE)
        .Where(t => t.tblSentEmail.UserID == UserId)
        .Where(t => t.tblSentEmail.blnOutlookRec == true || t.tblSentEmail.tblMerges.blnOutlookRec == true)
        .Where(s => s.tblSentEmail.tblRecipients.Any(o => o.strEmailAddress.Contains(strSearch)) || s.tblSentEmail.strSubject.Contains(strSearch) || s.tblSentEmail.tblRecipients.Any(r => r.strDisplayName.Contains(strSearch)))
        .OrderByDescending(t => t.dtmEvent)
        .Take(intNumRecords)
        .ToList();
    break;
case Constants.CLICKED:
    lstQueryEvents = db.tblEmailEvents
        .Where(t => t.strType.ToUpper() == Constants.CLICKED_TYPE)
        .Where(t => t.tblSentEmail.UserID == UserId)
        .Where(t => t.tblSentEmail.blnOutlookRec == true || t.tblSentEmail.tblMerges.blnOutlookRec == true)
        .Where(s => s.tblSentEmail.tblRecipients.Any(o => o.strEmailAddress.Contains(strSearch)) || s.tblSentEmail.strSubject.Contains(strSearch) || s.tblSentEmail.tblRecipients.Any(r => r.strDisplayName.Contains(strSearch)))
        .OrderByDescending(t => t.dtmEvent)
        .Take(intNumRecords)
        .ToList();
    break;

You can create LINQ queries in multiple statements and unless you need the results (eg by calling ToList ) it will not be executed. So you could do following:

var lstQueryEventsQuery = db.tblEmailEvents
        .Where(t => t.tblSentEmail.UserID == UserId)
        .Where(t => t.tblSentEmail.blnOutlookRec == true || t.tblSentEmail.tblMerges.blnOutlookRec == true)
        .Where(s => s.tblSentEmail.tblRecipients.Any(o => o.strEmailAddress.Contains(strSearch)) || s.tblSentEmail.strSubject.Contains(strSearch) || s.tblSentEmail.tblRecipients.Any(r => r.strDisplayName.Contains(strSearch)));

switch(yourVariable)
{
    case Constants.OPENED:
        lstQueryEventsQuery = lstQueryEventsQuery.Where(t => t.strType.ToUpper() == Constants.OPENED_TYPE)
        break;
    case Constants.CLICKED:
        lstQueryEventsQuery = lstQueryEventsQuery.Where(t => t.strType.ToUpper() == Constants.OPENED_TYPE)
        break;
}

lstQueryEvents = lstQueryEventsQuery.OrderByDescending(t => t.dtmEvent)
    .Take(intNumRecords)
    .ToList();

You could split up the chain into separate calls like this:

var emailEvents = db.tblEmailEvents.AsQueryable();
switch(myConstant)
{
    case Constants.OPENED:
        emailEvents = emailEvents.Where(t => t.strType.ToUpper() == Constants.OPENED_TYPE;
    break;
    case Constants.CLICKED:
        emailEvents = emailEvents.Where(t => t.strType.ToUpper() == Constants.CLICKED_TYPE;
    break;
    //etc
}

lstQueryEvents = emailEvents.Where(t => t.tblSentEmail.UserID == UserId)
    .Where(t => t.tblSentEmail.blnOutlookRec == true || t.tblSentEmail.tblMerges.blnOutlookRec == true)
    .Where(s => s.tblSentEmail.tblRecipients.Any(o => o.strEmailAddress.Contains(strSearch)) || s.tblSentEmail.strSubject.Contains(strSearch) || s.tblSentEmail.tblRecipients.Any(r => r.strDisplayName.Contains(strSearch)))
    .OrderByDescending(t => t.dtmEvent)
    .Take(intNumRecords)
    .ToList();

This works because the result of each call returns IEnumerable , which isn't evaluated until you attempt to use it (or call ToList ).

I would try something like this. Build a predicate based on your constant value. I guess you could also directly pass the predicate to your method as a parameter.

Func<T, bool> predicate;
switch(constant)
{
    case Constants.OPENED:
        predicate = (T t) => (t.strType.ToUpper() == Constants.OPENED_TYPE);
        break;
    case Constants.CLICKED:
        predicate = (T t) => (t.strType.ToUpper() == Constants.CLICKED_TYPE);
        break;
}

lstQueryEvents = db.tblEmailEvents
    .Where(predicate)
    .Where(t => t.tblSentEmail.UserID == UserId)
    .Where(t => t.tblSentEmail.blnOutlookRec == true || t.tblSentEmail.tblMerges.blnOutlookRec == true)
    .Where(s => s.tblSentEmail.tblRecipients.Any(o => o.strEmailAddress.Contains(strSearch)) || s.tblSentEmail.strSubject.Contains(strSearch) || s.tblSentEmail.tblRecipients.Any(r => r.strDisplayName.Contains(strSearch)))
    .OrderByDescending(t => t.dtmEvent)
    .Take(intNumRecords)
    .ToList();

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