LINQ的多对多关系加入
问题描述:
我有4个表,UserCredential
,UserProfile
,UserRoles
和Role
LINQ的多对多关系加入
var user = (from uc in Db.UserCredentials
join up in Db.UserProfiles on uc.UserId equals up.UserId
join ur in Db.UserRoles on uc.UserId equals ur.UserId
select new {
Credetial = uc,
Profile = up,
Roles = Db.Roles.Where(r => r.RoleId == ur.RoleId)})
.FirstOrDefault();
UserRole
有UserId
和RoleId
,使用户可以拥有多个角色。
上述代码生成的查询似乎效率不高。任何人都可以提出更好的代码
答
首先,由于我们担心性能,请确保您的数据库在所有这些UserId和RoleId列上都有索引。
由于您有多个UserRoles,包括它在连接中浪费地增加了查询的基数,然后调用FirstOrDefault将其拉回到一。一?你没有展示你如何选择一个特定的用户,但我会留给你解决,除非它在你的一个数据源中被过滤。
此外,匿名对象上的角色属性:每次触摸它时,都会触及数据库。这很可能是性能问题的根源。如果缓存该信息是可以接受的,则用ToList()调用完成子查询将是谨慎的。
该子查询本身可能是另一个麻烦来源,特别是如果使用ToList - 它将是另一次到数据库的行程,所以请确保将主查询的基数保持为低以控制行程数。
var user = (from uc in Db.UserCredentials
join up in Db.UserProfiles on uc.UserId equals up.UserId
//where uc.UserId == somePassedInUserId /* add this line if your datasources aren't filtered */
select new {
Credetial = uc,
Profile = up,
Roles = (from ur in Db.UserRoles join r in Db.Roles on ur.RoleId equals r.RoleId
where ur.UserId == uc.UserId select r).ToList()
.FirstOrDefault();
EF会自动为关系创建导航属性,因此您不需要使用连接。 – 2014-11-09 05:26:09
您将EF和LINQ指示为SQL。你在用哪个?每个生成的SQL可能会有很大的不同。发布生成的SQL并指出您觉得效率低下的地方。无论如何,考虑把它看作一个对象图,而不是用连接来设置,你可能会发现一个更好的选择。 – 2014-11-10 01:30:47