从表达式中重构 LINQ JOIN



我有一个LINQ-to-SQL表达式,它重复了3次,只有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 语句:

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

这可能吗?

您可以像这样重构重复的代码。

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

您是否尝试创建这样的方法:

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

最新更新