【发布时间】:2019-02-05 08:34:10
【问题描述】:
我使用数据库优先方法。我的数据库中有以下表格:
[Country](ID, Name)
[Status](ID, Name)
[User](ID, Name)
[Object](ID, StatusID, Name)
[ObjectXCountries](ObjectID, CountryID)
[ObjectXUser](ObjectID, UserID)
现在实体框架创建这些实体:
Country { ID, Name }
User { ID, Name }
Status { ID, Name }
Object { ID, StatusID, Status, Name, Countries, Users }
要编辑对象列表,UI 需要以下 JSON 结构:
{
cnt: [ { id: 1, name: 'some country', ...}, ],
usr: [ { id: 1, name: 'some user', ...}, ],
st: [ { id: 1, name: 'some status', ...}, ],
objects: [ { id: 1, name: 'some name', st: 1, cnt: [ 1, 2, 3 ], usr: [ 1, 2, 3] }, ... ]
}
获取国家、用户和状态的列表很简单,但我如何获取具有关联 ID 的对象列表?现在我有以下代码,导致查询效率非常低:
ctx.Object.Select(rec => new ObjectDTO {
ID = rec.ID,
Name = rec.Name,
StatusID = rec.StatusID,
UserIDs = rec.Users.Select(usr => usr.ID).ToArray(),
CountryIDs = rec.Countries.Select(cnt => cnt.ID).ToArray()
});
它转换为 sql,这取决于对象的数量,它选择所有对象,然后为每个对象创建一个选择查询以获取用户 ID 和国家/地区列表。如果我有一百个对象,它将导致 101 个查询。第一个获取对象列表,100 个获取连接的 ID。 (UPD:201 次查询,每个实体有两个额外的查询来获取用户 ID 和国家/地区 ID)。
是否可以仅使用 3 个选择查询来选择此信息? 在sql中很容易做到,但是我想知道在Entity Framework中如何做到。
UPD:在 SQL 中我只需要编写 3 个选择语句:
SELECT * FROM [Object]
SELECT * FROM [ObjectXCountries]
SELECT * FROM [ObjectXUser]
从代码中调用此查询,然后加入 ObjectID 上的三个结果集。也许有一些方法可以使表 [ObjectXCountries] 和 [ObjectXUser] 在实体上下文中可用,所以我可以编写类似的代码?
UPD:我使用的是 Entity Framework 6.2。
【问题讨论】:
-
从解释看来您使用的是 EF Core 版本早于 2.1,对吗?如果是,考虑升级以获得Optimization of correlated subqueries
-
不,我使用 Entity Framework 6.2 版。我应该在描述中提到它,对不起。
-
嗯,你确定吗?很抱歉再次询问,但在 EF6.2
ToArray在运行时产生不支持的异常,并且没有它我得到一个 SQL 查询(具有类似的实体结构)。可以显示生成的 SQL 吗?
标签: c# .net entity-framework