如何重新编写以下查询以消除foreach
循环并对数据库进行一次调用?
List<AuditLog> auditLogs = new List<AuditLog>();
foreach (TableRecordGuidPair pair in allTablesRecords)
{
var auditLogsFromDatabase = databaseContext.AuditLog.OrderBy(x => x.EventDateUtc)
.Where
(x => x.TableName == pair.TableName &&
x.RecordId == pair.RecordID)
.Select(auditLog => new AuditLog
{
AuditLogId = auditLog.AuditLogId,
}).ToList();
auditLogs.AddRange(auditLogsFromDatabase);
}
return auditLogs;
答案 0 :(得分:2)
您可以使用SelectMany选择所有列表,如下所示:
return allTablesRecords
.SelectMany(pair =>
databaseContext.AuditLog.OrderBy(x => x.EventDateUtc)
.Where(x => x.TableName == pair.TableName && x.RecordId == pair.RecordID)
.Select(auditLog => new AuditLog
{
AuditLogId = auditLog.AuditLogId,
})
)
.ToList();
或者,您可以进行加入
return (from allTableRecords pair
join databaseContext.AuditLog auditLog
on new { pair.TableName, pair.RecordId } equals new { auditLog.TableName, auditLog.RecordId }
select new {
AutitLogId = auditLog.AuditLogId
})
.ToList();
答案 1 :(得分:1)
使用来自allTablesRecords的通配符对键进行投影,然后使用查询中的contains进行比较。仅当allTablesRecords只有少于约5000条记录时才有效。如果不止于此,您可能会遇到运行时异常,并应考虑制作存储过程。
IEnumerable<string> pairKeys = allTablesRecords.Select(pair => pair.TableName + "¿" + pair.RecordID);
return databaseContext.AuditLog.OrderBy(x => x.EventDateUtc)
.Where(x => pairKeys.Contains(x.TableName + "¿" + x.RecordID))
.Select(auditLog => new AuditLog
{
AuditLogId = auditLog.AuditLogId,
}).ToList();