我目前正在使用npgsql PostgreSQL适配器在ASP.NET Core 1.0中使用Linq to SQL。
我有以下LINQ查询,该查询应返回类型Device
var devices = DeviceConfigurationDbContext.UserGroupMembershipList
.AsNoTracking()
.Where(ugml => ugml.UserId == currentUser.Id)
.Select(ugml => ugml.UserGroup)
.SelectMany(ug => ug.UserGroupAccessList)
.Select(uga => uga.DeviceGroup)
.SelectMany(dg => dg.Devices);
此代码的目的是通过对Where
执行UserGroupMembershipList
找到允许某个用户访问的所有设备,然后加入其余表,直到列表为已到达Device
。
实体之间的关系是:
UserGroupMembershipList
- (多对一) - > UserGroup
- (一对多) - > UserGroupAccessList
- (多对一) - > DeviceGroup
- (一对多) - > Device
UserGroupAccessList
是一个ACL,充当UserGroup
和DeviceGroup
之间的多对多联接表。
然后生成SQL查询:
SELECT "ugml"."Id", "ugml"."DeviceGroupId", "d"."DeviceGroupId", "d"."Name", "uga.DeviceGroup"."Id"
FROM "Device" AS "ugml"
INNER JOIN "UserGroup" AS "ugml.UserGroup" ON "ugml"."UserGroupId" = "ugml.UserGroup"."Id"
CROSS JOIN "UserGroupAccess" AS "uga"
INNER JOIN "DeviceGroup" AS "uga.DeviceGroup" ON "uga"."DeviceGroupId" = "uga.DeviceGroup"."Id"
CROSS JOIN "Device" AS "d"
WHERE ("ugml"."UserId" = @__currentUser_Id_0) AND ("ugml.UserGroup"."Id" = "ugml"."UserGroupId")
反过来会产生错误
在迭代a的结果时数据库中发生异常 查询。 Npgsql.NpgsqlException:42703:列ugml.UserGroupId没有 存在
这似乎是因为SQL查询由于某种原因正在执行SELECT FROM "Device" AS ugml
而不是SELECT FROM "UserGroupMembershipList" AS ugml
。此外,where子句因此而显得不正确。
在Linq查询方面,我做错了吗?还有其他方法可以解决我正在努力避免此错误的问题吗?
修改
我找到了一个解决方案,虽然它不太理想。
var devices = (await DeviceConfigurationDbContext.UserGroupMembershipList
.AsNoTracking()
.Where(ugml => ugml.UserId == currentUser.Id)
.Include(o => o.UserGroup)
.ThenInclude(o => o.UserGroupAccessList)
.ThenInclude(o => o.DeviceGroup)
.ThenInclude(o => o.Devices)
.ToListAsync())
.Select(ugml => ugml.UserGroup)
.SelectMany(ug => ug.UserGroupAccessList)
.Select(uga => uga.DeviceGroup)
.SelectMany(dg => dg.Devices);
这使得查询在WHERE
之后连接表,然后将整个结果集作为List
返回,标准Linq可以在内存中对其进行操作。它不太理想,因为我之后需要进一步细化查询,与数据库中的所有内容相比,传输的数据更多。
答案 0 :(得分:2)
为什么不发出一个Select查询并将结果预测出来?
var devices = await DeviceConfigurationDbContext.UserGroupMembershipList
.AsNoTracking()
.Where(ugml => ugml.UserId == currentUser.Id)
.Include(o => o.UserGroup)
.ThenInclude(o => o.UserGroupAccessList)
.ThenInclude(o => o.DeviceGroup)
.ThenInclude(o => o.Devices)
.SelectMany(ugml => ugml.UserGroup.UserGroupAccessLists
.Select(ugal => ugal.DeviceGroup.Devices)
.ToListAsync();
尝试以上查询,如果您发现任何问题,请告知我们。
如果你仍然看到问题,我怀疑npgsql适配器在适配器周围仍然有一些皱纹,因为我在github的npgsql分支中跟踪了一些类似的错误。