LINQ语句中的条件IF语句

时间:2015-09-22 21:41:19

标签: c# sql-server linq azure

我在Azure中托管了一个SQL数据库以及我的Web应用程序(两者都在同一个数据中心)。

我有一些类似的LINQ查询,这些查询基本上只在 .Where()子句中有所不同。

由于查询类似,我不想在任何地方进行代码重复,但我不认为 LINQ允许我在语句中使用条件IF。

我在下面添加了一个代码段,因此任何关于此的指针都会有所帮助。我还应该提到它是查询视图而不是表格。

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;

3 个答案:

答案 0 :(得分:2)

您可以在多个语句中创建LINQ查询,除非您需要结果(例如,通过调用ToList),否则它将不会被执行。所以你可以这样做:

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();

答案 1 :(得分:0)

您可以将链分割为单独的调用,如下所示:

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();

这是有效的,因为每次调用的结果都会返回IEnumerable,在您尝试使用它(或调用ToList)之前,不会对其进行评估。

答案 2 :(得分:0)

我会尝试这样的事情。根据您的常量值构建谓词。我猜你也可以直接将谓词作为参数传递给你的方法。

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();