我需要使用EF查询多个表中的多个列。当我在选择查询中不包含M-M关系时,一切顺利且性能良好。
使用M-M关系查询:
result = (from s in db.Member
.Include(i => i.Category)
.Include(i => i.MemberWorkEntity)
.Include(i => i.Status)
.Include(i => i.DiscountMethod)
.Where(i => i.C_deleted == null)
select new MemberDTO
{
memberNumber = s.memberNumber,
name = s.name,
status = s.Status.name,
email = s.email,
phone = s.phone,
mobile = s.mobile,
fax = s.fax,
workEntity = (from e in db.WorkEntity.Where(i => i.workEntityLevelID == 2)
join sc in s.MemberWorkEntity on e.workEntityID equals sc.workEntityID
select e.name).FirstOrDefault(),
category = s.Category.name,
discountMethod = s.DiscountMethod.name,
delegate = s.delegate ? "Yes" : "No",
leader = s.leader ? "Yes" : "No"
}).AsNoTracking().ToList<MemberDTO>();
30000记录执行时间(ms):
|1st Execution: 1376
|2nd Execution: 160
|3rd Execution: 145
没有M-M关系的查询:
result = (from s in db.Member
.Include(i => i.Category)
.Include(i => i.MemberWorkEntity)
.Include(i => i.Status)
.Include(i => i.DiscountMethod)
.Where(i => i.C_deleted == null)
select new MemberDTO
{
memberNumber = s.memberNumber,
name = s.name,
status = s.Status.name,
email = s.email,
phone = s.phone,
mobile = s.mobile,
fax = s.fax,
//removed M-M Relationship Query
category = s.Category.name,
discountMethod = s.DiscountMethod.name,
delegate = s.delegate ? "Yes" : "No",
leader = s.leader ? "Yes" : "No"
}).AsNoTracking().ToList<MemberDTO>();
30000记录执行时间(ms):
|1st Execution: 1286
|2nd Execution: 79
|3rd Execution: 67
为什么会有这样的差异(平均慢2倍)?如何提高查询性能?
更新:根据@ AndreFilimon的建议更新了我的查询:
IEnumerable<WorkEntity> workEntities = db.WorkEntity.AsNoTracking().Where(i => i.workEntityLevelID == 2);
result = (from s in db.Member
.Include(i => i.Category)
.Include(i => i.Status)
.Include(i => i.DiscountMethod)
.Where(i => i.C_deleted == null)
select new MemberDTO
{
memberNumber = s.memberNumber,
name = s.name,
status = s.Status.name,
email = s.email,
phone = s.phone,
mobile = s.mobile,
fax = s.fax,
workEntity = (from e in workEntities
join sc in s.MemberWorkEntity on e.workEntityID equals sc.workEntityID
select e.name).FirstOrDefault(),
category = s.Category.name,
discountMethod = s.DiscountMethod.name,
delegate = s.delegate ? "Yes" : "No",
leader = s.leader ? "Yes" : "No"
}).AsNoTracking().ToList<MemberDTO>();
30000记录执行时间(ms):
|1st Execution: 1364
|2nd Execution: 122
|3rd Execution: 120
更新:在@agfc建议的基础上为我的会员表添加了一个简单的索引:
IEnumerable<WorkEntity> workEntities = db.WorkEntity.AsNoTracking().Where(i => i.workEntityLevelID == 2);
result = (from s in db.Member
.Include(i => i.Category)
.Include(i => i.Status)
.Include(i => i.DiscountMethod)
.Where(i => i.C_deleted == null)
select new MemberDTO
{
memberNumber = s.memberNumber,
name = s.name,
status = s.Status.name,
email = s.email,
phone = s.phone,
mobile = s.mobile,
fax = s.fax,
workEntity = (from e in workEntities
join sc in s.MemberWorkEntity on e.workEntityID equals sc.workEntityID
select e.name).FirstOrDefault(),
category = s.Category.name,
discountMethod = s.DiscountMethod.name,
delegate = s.delegate ? "Yes" : "No",
leader = s.leader ? "Yes" : "No"
}).AsNoTracking().ToList<MemberDTO>();
30000记录执行时间(ms):
|1st Execution: 1544
|2nd Execution: 109
|3rd Execution: 105
更新:根据@ Klinger的回答更改了查询:
result = db.MemberWorkEntity.Where(mw => mw.WorkEntity.workEntityLevelID == 2 && mw.Member.C_deleted == null)
.Select(s => new MemberDTO
{
memberNumber = mw.Member.memberNumber,
name = mw.Member.name,
status = mw.Member.Status.name,
email = mw.Member.email,
phone = mw.Member.phone,
mobile = mw.Member.mobile,
fax = mw.Member.fax,
workEntity = mw.WorkEntity.name,
category = mw.Member.Category.name,
discountMethod = mw.Member.DiscountMethod.name,
@delegate = mw.Member.@delegate ? "Yes" : "No",
leader = mw.Member.leader ? "Yes" : "No"
}).ToList();
30000记录执行时间(ms):
|1st Execution: 1427
|2nd Execution: 80
|3rd Execution: 76
答案 0 :(得分:1)
如果不查看实体的确切形状,请执行以下操作:
result = db.MemberWorkEntity.Where(mw => mw.WorkEntity.workEntityLevelID == 2 && mw.Member.C_deleted == null)
.Select(s => new MemberDTO
{
memberNumber = mw.Member.memberNumber,
name = mw.Member.name,
status = mw.Member.Status.name,
email = mw.Member.email,
phone = mw.Member.phone,
mobile = mw.Member.mobile,
fax = mw.Member.fax,
workEntity = mw.WorkEntity.name,
category = mw.Member.Category.name,
discountMethod = mw.Member.DiscountMethod.name,
@delegate = mw.Member.@delegate ? "Yes" : "No",
leader = mw.Member.leader ? "Yes" : "No"
}).ToList();
无需使用Include
因为您投射到DTO而不是实体。 DTO将不具有您所包含实体的导航属性。 <{1}}用于在返回实体时进行预先加载。
答案 1 :(得分:0)
尝试在where子句之后移动包含,你也应该在这里获得一些整体性能: 同时将内部查询移出主查询以避免加入如下:
onClick