2017-01-09 18 views
1

У меня есть выражение LINQ-to-SQL, которое повторяется 3 раза, при этом изменяется только оператор Join.Рефакторинг LINQ JOIN из выражения

switch (elmntType) 
{ 
    case ElementType.Dictionary: 
     auditLogs = db.st_element_audit_log.Where(al => /* some conditions */) 
         .Join(db.stt_dictionary, 
          auditLog => auditLog.element_id, 
          dictionary => dictionary.id, 
          (auditLog, dictionary) => new AuditLogAndDict { AuditLog = auditLog, Dictionary = dictionary }) 
         .Where(ald => /* some conditions */) 
         .OrderByDescending(ald => /* some conditions */) 
         .Select(ald => ald.AuditLog); 
     break; 

    case ElementType.Concept: 
     auditLogs = db.st_element_audit_log.Where(al => /* some conditions */) 
         .Join(db.stt_concept, 
          auditLog => auditLog.element_id, 
          concept => concept.id, 
          (auditLog, concept) => new {auditLog, concept}) 
         .Join(db.stt_dictionary, 
          anon => anon.concept.dictionary_id, 
          dictionary => dictionary.id, 
          (anon, dictionary) => new AuditLogAndDict {AuditLog = anon.auditLog, Dictionary = dictionary}) 
         .Where(ald => /* some conditions */) 
         .OrderByDescending(ald => /* some conditions */) 
         .Select(ald => ald.AuditLog); 
     break; 

    case ElementType.Term: 
     auditLogs = db.st_element_audit_log.Where(al => /* some conditions */) 
         .Join(db.stt_term, 
          auditLog => auditLog.element_id, 
          term => term.id, 
          (auditLog, term) => new {auditLog, term}) 
         .Join(db.stt_concept, 
          anon => anon.term.concept_id, 
          concept => concept.id, 
          (anon, concept) => new {anon.auditLog, concept}) 
         .Join(db.stt_dictionary, 
          anon => anon.concept.dictionary_id, 
          dictionary => dictionary.id, 
          (anon, dictionary) => new AuditLogAndDict {AuditLog = anon.auditLog, Dictionary = dictionary}) 
         .Where(ald => /* some conditions */) 
         .OrderByDescending(ald => /* some conditions */) 
         .Select(ald => ald.AuditLog); 
     break; 

    default: 
     throw new ArgumentException("Unsupported ElementType enumeration.", nameof(elmntType)); 
} 

То, что я хотел бы выяснить, могу ли я реорганизовать Join заявления, оставив только один экземпляр всего заявления LINQ с Join поступающего из коммутатора заявления:

switch (elmntType) 
{ 
    case ElementType.Dictionary: 
     // build .Join() statement 
     break; 

    case ElementType.Concept: 
     // build .Join() statement 
     break; 

    case ElementType.Term: 
     // build .Join() statement 
     break; 

    default: 
     throw new ArgumentException("Unsupported ElementType enumeration.", nameof(elmntType)); 
} 

var auditLogs = db.st_element_audit_log.Where(al => /* some conditions */) 
          // use the custom .Join() statement here 
          .Where(ald => /* some conditions */) 
          .OrderByDescending(ald => /* some conditions */) 
          .Select(ald => ald.AuditLog); 

Возможно ли это?

+0

Щелкните правой кнопкой мыши общий код linq, а затем выберите Refactor, который позволит вам извлечь один метод. Если это не сработает для вас, вы также можете создавать выражения LINQ и использовать методы замены строк для изменения окончательного запроса. –

ответ

2

Вы можете реорганизовать из дублированного кода, как это.

var filtered = db.st_element_audit_log.Where(al => /* some conditions */) 
IQueryable<AuditLogAndDict> joined = null; 
switch (elmntType) 
{ 
    case ElementType.Dictionary: 
     joined = filtered.Join(db.stt_dictionary, 
      auditLog => auditLog.element_id, 
      dictionary => dictionary.id, 
      (auditLog, dictionary) => new AuditLogAndDict { AuditLog = auditLog, Dictionary = dictionary }) 
     break; 

    case ElementType.Concept: 
     joined = filtered 
      .Join(db.stt_concept, 
       auditLog => auditLog.element_id, 
       concept => concept.id, 
       (auditLog, concept) => new {auditLog, concept}) 
      .Join(db.stt_dictionary, 
       anon => anon.concept.dictionary_id, 
       dictionary => dictionary.id, 
       (anon, dictionary) => new AuditLogAndDict {AuditLog = anon.auditLog, Dictionary = dictionary}) 
     break; 

    case ElementType.Term: 
     joined = filtered 
      .Join(db.stt_term, 
       auditLog => auditLog.element_id, 
       term => term.id, 
       (auditLog, term) => new {auditLog, term}) 
      .Join(db.stt_concept, 
       anon => anon.term.concept_id, 
       concept => concept.id, 
       (anon, concept) => new {anon.auditLog, concept}) 
      .Join(db.stt_dictionary, 
       anon => anon.concept.dictionary_id, 
       dictionary => dictionary.id, 
       (anon, dictionary) => new AuditLogAndDict {AuditLog = anon.auditLog, Dictionary = dictionary}) 
     break; 

    default: 
     throw new ArgumentException("Unsupported ElementType enumeration.", nameof(elmntType)); 
} 

auditLogs = joined 
    .Where(ald => /* some conditions */) 
    .OrderByDescending(ald => /* some conditions */) 
    .Select(ald => ald.AuditLog); 
+0

Да, это будет сделано. Спасибо @juharr. Я думаю, что он не может быть реорганизован в метод/переменную, а не помещен в конструкцию IQueryable _in-between_? (Если это не ясно, просто игнорируйте его.) – awj

-1

ли вы пытаетесь создать метод, как это:

static object MyJoin(object x) 
     { 
      return x.Join(db.stt_dictionary, 
      auditLog => auditLog.element_id, 
      dictionary => dictionary.id, 
      (auditLog, dictionary) => new AuditLogAndDict { AuditLog = auditLog, Dictionary = dictionary }); 

     } 

 Смежные вопросы

  • Нет связанных вопросов^_^