2015-09-22 2 views
0

У меня есть база данных SQL, размещенная в Azure вместе с моим веб-приложением (как в том же центре обработки данных).Условный оператор IF в операторе LINQ

У меня есть несколько похожих запросов LINQ, которые в основном отличаются только предложением .

Поскольку запросы похожи, я не хочу, чтобы у меня было перекодирование кода в любом месте, но я не знаю LINQ позволяет мне иметь условные IFs в операторах.

Я добавил фрагмент кода ниже, поэтому любые указатели на это были бы полезны. Я должен также упомянуть, что он запрашивает представление, а не таблицу.

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; 
+0

Может ли 'Constants.OPENED' и' Constants.OPENED_TYPE' быть сделано то же самое (перечисление?)? То же самое для clicked, clicked_type. Тогда что бы вы ни переключали, это то, что вам нужно в предложении where. Или напишите метод с параметром, который входит в предложение where. DRY. –

+0

@BenKnoble 'Constants.OPENED' и' Constants.OPENED_TYPE' не являются перечислениями, но они являются просто закодированными значениями (т.е. 'Constants.OPENED' является строковым литералом' OPENED' и 'Constants.OPENED_TYPE' является string literal 'O'. Что я могу сделать? –

+0

Ну, если они одинаковые, то вместо того, чтобы делать« switch (someValue) case blah: break; case otherblah: break; », то вы можете сделать' query = source .Where (t => t.strType.ToUpper() == someValue) ... 'См. Мощность? –

ответ

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

Ahh, я вижу .. Я могу написать e все, что я хочу, и прямо перед тем, как выйти из своего метода, я могу выполнить его через '.ToList()', чтобы получить результаты благодаря! –

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).

+0

Это не сработает, потому что 'emailEvents' будет выведено как' DbSet 'и' Where' возвращает 'IQueryable '. – MarcinJuraszek

+0

@MarcinJuraszek, вы правы, спасибо. Забыл 'AsQueryable'. –

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(); 
Смежные вопросы