如何用单条LINQ语句统计多表中符合条件的同VendorID记录数
合并多表LINQ统计方案
场景说明
现有Orders、Subscribe、Notes三张数据表,均包含VendorID、Date、Status字段,需统计三张表中满足VendorID=34、Date='2022-09-01'且Status='Active'的记录数量,可通过单条LINQ语句同时获取各表单独计数或总计数。
方案1:获取总记录数
方式A:利用公共接口(推荐)
先定义一个包含共同字段的接口,让三个实体类实现该接口:
public interface IVendorDateStatus { int VendorID { get; set; } DateTime Date { get; set; } string Status { get; set; } } // 假设Orders、Subscribe、Notes实体类均实现IVendorDateStatus接口
然后通过Concat拼接符合条件的查询结果,再统计总数:
var totalCount = Orders.Where(x => x.VendorID == 34 && x.Date == new DateTime(2022, 9, 1) && x.Status == "Active") .Cast<IVendorDateStatus>() .Concat(Subscribe.Where(x => x.VendorID == 34 && x.Date == new DateTime(2022, 9, 1) && x.Status == "Active")) .Concat(Notes.Where(x => x.VendorID == 34 && x.Date == new DateTime(2022, 9, 1) && x.Status == "Active")) .Count();
方式B:无公共接口时使用dynamic
如果无法修改实体类添加接口,可通过dynamic兼容不同类型:
var totalCount = (from o in Orders where o.VendorID == 34 && o.Date == new DateTime(2022, 9, 1) && o.Status == "Active" select o) .Concat(from s in Subscribe where s.VendorID == 34 && s.Date == new DateTime(2022, 9, 1) && s.Status == "Active" select s as dynamic) .Concat(from n in Notes where n.VendorID == 34 && n.Date == new DateTime(2022, 9, 1) && n.Status == "Active" select n as dynamic) .Count();
方案2:同时获取各表单独计数与总计数
通过匿名对象一次性封装三个表的计数结果,EF会自动将其转换为高效的数据库查询:
var countResult = new { OCount = Orders.Count(o => o.VendorID == 34 && o.Date == new DateTime(2022, 9, 1) && o.Status == "Active"), SCount = Subscribe.Count(s => s.VendorID == 34 && s.Date == new DateTime(2022, 9, 1) && s.Status == "Active"), NCount = Notes.Count(n => n.VendorID == 34 && n.Date == new DateTime(2022, 9, 1) && n.Status == "Active"), TotalCount = Orders.Count(o => o.VendorID == 34 && o.Date == new DateTime(2022, 9, 1) && o.Status == "Active") + Subscribe.Count(s => s.VendorID == 34 && s.Date == new DateTime(2022, 9, 1) && s.Status == "Active") + Notes.Count(n => n.VendorID == 34 && n.Date == new DateTime(2022, 9, 1) && n.Status == "Active") }; // 使用示例:countResult.OCount、countResult.TotalCount
注意事项
- 避免在客户端拼接数据:不要先调用
ToList()拉取全表数据再统计,确保查询逻辑在数据库端执行,提升性能。 - 日期比较使用
DateTime类型:直接用new DateTime(2022,9,1)而非字符串,避免因日期格式差异导致的查询错误。 - 接口方式更易维护:定义公共接口可让代码更清晰,后续扩展新表时只需实现接口即可复用逻辑。
内容的提问来源于stack exchange,提问作者Ramanan
相关产品推荐
相关产品推荐

