在 Linq 和 EFCore 中查询多对多关系
Query many to many relationship in Linq and EFCore
我正在尝试在 linq 中执行以下查询,但是我遇到了异常错误,尽管我的查询看起来没问题。故事是这样的:
图
我在用户和组织之间建立了多对多关系。一个用户可以是多个组织的一部分,一个组织可以有多个用户。
我想查询什么
所以给定一个用户id,我想查询我所属的所有组织中的所有团队成员(用户)。所以
- 输入:用户X id(guid),此用户属于机构A,机构B
输出:
用户 A,组织 A
用户 B,组织 A
用户 C,组织 B
实际查询
我虽然这会做到这一点
var user = db.Users.Include(q => q.UserOrganization).SingleOrDefault( q => q.Id == id.ToString());
var members = (from us in db.Users.Include(q => q.UserOrganization)
let orgs = user.UserOrganization.Select(z => z.OrganizationId)
where us.UserOrganization.Any(q => orgs.Contains(q.OrganizationId) )
select new UserResource{
id = Guid.Parse(us.Id),
email = us.Email
}
).ToArray();
我的查询在 where 子句上失败,错误为:
Processing of the LINQ expression 'AsQueryable<long>((Unhandled parameter: __Select_0))' by 'NavigationExpandingExpressionVisitor' failed. This may indicate either a bug or a limitation in EF Core
不确定要在查询中更改什么。请帮忙。
PS:我最初在MySql中写的查询如下:
SELECT UU.`Id`, UU.`Email`, UUO.`OrganizationId`
FROM aspnetusers AS UU
LEFT JOIN userorganization AS UUO ON UUO.`UserId` = `UU`.Id
WHERE UUO.`OrganizationId` IN
(
SELECT UO.`OrganizationId` FROM aspnetusers AS U
LEFT JOIN userorganization AS UO ON UO.UserId = U.Id
WHERE u.Id = '6caa67e7-69f3-49a3-ad61-10b07d379f10'
)
AND UU.Id != '6caa67e7-69f3-49a3-ad61-10b07d379f10'
"SingleOrDefault" 始终执行查询。用户不是 IQueryable。
因此 let orgs = user.UserOrganization.Select(z => z.OrganizationId)
无法转换为 SQL,请在查询之前使用纯 C# 执行 var orgs = user.UserOrganization.Select(z => z.OrganizationId)
。这不能用于 SQL-查询。
组织是 IList<int>
它会起作用。
但最好能找到一个只用一个查询就可以解决的方案。给你两个。
SingleOrDefault 可能没有用,没有它比使用简单的 IQueryable 更好。 "Any" 通常可以通过简单的(内部)连接来实现,如果表之间存在匹配,则只返回值。这与 Where - Any - Contains
相同
我正在尝试在 linq 中执行以下查询,但是我遇到了异常错误,尽管我的查询看起来没问题。故事是这样的:
图
我在用户和组织之间建立了多对多关系。一个用户可以是多个组织的一部分,一个组织可以有多个用户。
我想查询什么
所以给定一个用户id,我想查询我所属的所有组织中的所有团队成员(用户)。所以
- 输入:用户X id(guid),此用户属于机构A,机构B
输出:
用户 A,组织 A
用户 B,组织 A
用户 C,组织 B
实际查询
我虽然这会做到这一点
var user = db.Users.Include(q => q.UserOrganization).SingleOrDefault( q => q.Id == id.ToString());
var members = (from us in db.Users.Include(q => q.UserOrganization)
let orgs = user.UserOrganization.Select(z => z.OrganizationId)
where us.UserOrganization.Any(q => orgs.Contains(q.OrganizationId) )
select new UserResource{
id = Guid.Parse(us.Id),
email = us.Email
}
).ToArray();
我的查询在 where 子句上失败,错误为:
Processing of the LINQ expression 'AsQueryable<long>((Unhandled parameter: __Select_0))' by 'NavigationExpandingExpressionVisitor' failed. This may indicate either a bug or a limitation in EF Core
不确定要在查询中更改什么。请帮忙。
PS:我最初在MySql中写的查询如下:
SELECT UU.`Id`, UU.`Email`, UUO.`OrganizationId`
FROM aspnetusers AS UU
LEFT JOIN userorganization AS UUO ON UUO.`UserId` = `UU`.Id
WHERE UUO.`OrganizationId` IN
(
SELECT UO.`OrganizationId` FROM aspnetusers AS U
LEFT JOIN userorganization AS UO ON UO.UserId = U.Id
WHERE u.Id = '6caa67e7-69f3-49a3-ad61-10b07d379f10'
)
AND UU.Id != '6caa67e7-69f3-49a3-ad61-10b07d379f10'
"SingleOrDefault" 始终执行查询。用户不是 IQueryable。
因此 let orgs = user.UserOrganization.Select(z => z.OrganizationId)
无法转换为 SQL,请在查询之前使用纯 C# 执行 var orgs = user.UserOrganization.Select(z => z.OrganizationId)
。这不能用于 SQL-查询。
组织是 IList<int>
它会起作用。
但最好能找到一个只用一个查询就可以解决的方案。给你两个。
SingleOrDefault 可能没有用,没有它比使用简单的 IQueryable 更好。 "Any" 通常可以通过简单的(内部)连接来实现,如果表之间存在匹配,则只返回值。这与 Where - Any - Contains
相同