如何为GroupJoin添加条件或使用多键关联优化日志查询
解决方案
你只需要把GroupJoin的单键关联改成和你最初查询语法一致的复合键关联即可,不需要额外加Where过滤,也不会影响其他类型的日志数据:
public static IQueryable<LogsViewModel> GetInvoiceNames(ApplicationDbContext db, IQueryable<LogsViewModel> query) { return query.GroupJoin( db.Invoice, // 左表关联键:同时匹配SourceContext和ObjectId logsVM => new { Key1 = logsVM.Log.SourceContext, Key2 = logsVM.Log.ObjectId }, // 右表关联键:固定匹配"Invoice"上下文,同时匹配id invoice => new { Key1 = "Invoice", Key2 = (int?)invoice.id }, (logsVM, invoices) => new LogsViewModel { Log = logsVM.Log, // 匹配不到时加空字符串,不影响原有Name值 Name = logsVM.Name + (invoices.FirstOrDefault()?.invoice_number ?? ""), UserName = logsVM.UserName }); }
原理说明
- 复合关联键会同时校验两个字段的值,只有日志的
SourceContext等于"Invoice"的时候,才会真正和Invoice表执行关联匹配,其他上下文的日志关联结果自然为空,不会修改原有Name值 - 左右两边的匿名类的属性名、属性类型必须完全一致,这里把
invoice.id转成int?是为了和ObjectId的可空类型匹配,否则会报匿名类类型不匹配的编译错误 - 不需要额外过滤日志,也不会丢失非Invoice类型的日志数据,完全符合你的拆分需求
其他关联方法(比如GetWarehouseNames、GetProductNames等)都可以按照这个模板修改,只需要替换对应的上下文常量、关联表、取值字段即可。
内容的提问来源于stack exchange,提问作者Piotrek
相关产品推荐
相关产品推荐

