我在生产环境中得到的查询非常慢。我想知道为什么以及是否有更好的方法来实现相同的结果。
public async Task<Membership> FindByEmailByAccessL1OrL3OrL4Async(string email)
{
return await (from m in this.Queryable()
where m.Email == email
&& (m.RoleMemberships.Select(r => r.RoleId).Contains(RoleConstants.ACCESSGRANTEDL1ID)
|| m.RoleMemberships.Select(r => r.RoleId).Contains(RoleConstants.ACCESSGRANTEDL3ID)
|| m.RoleMemberships.Select(r => r.RoleId).Contains(RoleConstants.ACCESSGRANTEDL4ID))
select m).SingleOrDefaultAsync();
}
简而言之,此查询的目的是通过电子邮件获取用户成员资格并继续登录。更多我获得了用户会员资格,更多的查询将会很慢。
谢谢,
大卫
修改
this.Queryable()
相当于执行select * from Memberships
。
Membership
表有很多角色,角色有很多成员资格。
此外,成员资格表最多需要12秒才能获得240行的登录信息。我必须按角色过滤,因为电子邮件值在系统中不是唯一的。只有一些角色可以访问登录,这些角色将拥有唯一的电子邮件。这就是我必须过滤的原因。此查询返回一个成员资格以继续登录,该成员资格已通过上述查询选择。所以没有IQueryable
,IEnumerable
或List
,只有SingleOrDefault
值。
答案 0 :(得分:3)
我认为生成的查询非常糟糕,因为你多次做同样的事情是:
m.RoleMemberships.Select(r => r.RoleId)
相反,您可以使用以下方法执行此操作:
public Task<Membership> FindByEmailByAccessL1OrL3OrL4Async(string email)
{
return (from m in this.Queryable()
where m.Email == email
&& (m.RoleMemberships.Any(
r => r.RoleId == RoleConstants.ACCESSGRANTEDL1ID
|| r.RoleID == RoleConstants.ACCESSGRANTEDL3ID
|| r.RoleID == RoleConstants.ACCESSGRANTEDL4ID)
select m).SingleOrDefaultAsync();
}
以上会让事情变得更好我猜。您可以使用调试器在两种情况下检查生成的查询。
另请注意,您无需等待结果,只需返回任务,调用者就需要等待它。
答案 1 :(得分:0)