Как эффективно выбрать сущность и идентификаторы связанных сущностей с Entity Framework - PullRequest
0 голосов
/ 05 февраля 2019

Я использую базу данных первым подходом.В моей базе данных есть следующие таблицы:

[Country](ID, Name)
[Status](ID, Name)
[User](ID, Name)
[Object](ID, StatusID, Name)
[ObjectXCountries](ObjectID, CountryID)
[ObjectXUser](ObjectID, UserID)

Теперь Entity Framework создает эти объекты:

Country { ID, Name }
User { ID, Name }
Status { ID, Name }
Object { ID, StatusID, Status, Name, Countries, Users }

Для редактирования списка объектов пользовательскому интерфейсу необходима следующая структура 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] }, ... ] 
}

Получение списка стран, пользователей и статусов тривиально, но как мне получить список объектов с идентификаторами, связанными с ними?Прямо сейчас у меня есть следующий код, который приводит к очень неэффективному запросу:

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, который зависит от количества объектов, он выбирает все объекты, а затем создает запрос выбора.для каждого из объектов получить список идентификаторов пользователей и стран.Если у меня есть сто объектов, это приведет к 101 запросу.Первый, чтобы получить список объектов и 100, чтобы получить идентификаторы подключенных.(UPD: 201 запрос, для каждой сущности есть два дополнительных запроса, чтобы получить идентификаторы пользователей и стран).

Можно ли выбрать эту информацию, используя только 3 запроса выбора?Это легко сделать в SQL, но я хочу знать, как я могу сделать это в Entity Framework.

UPD: В SQL я бы просто написал 3 оператора select:

SELECT * FROM [Object]
SELECT * FROM [ObjectXCountries]
SELECT * FROM [ObjectXUser]

Вызовите этот запрос из кода, а затем соедините три набора результатов по ObjectID.Может быть, есть какой-нибудь способ сделать таблицы [ObjectXCountries] и [ObjectXUser] доступными в контексте сущности, чтобы я мог написать похожий код?

UPD: Я использую Entity Framework 6.2.

1 Ответ

0 голосов
/ 05 февраля 2019

Хорошо, после того, как много гуглил и пробовал разные способы, я нашел простое и работающее решение.

Несколько запросов являются результатом отложенной загрузки.Если я "включу" мои навигационные свойства, он получит все в одном запросе.Это может быть достигнуто с помощью следующего кода:

ctx
.Object
.Include("Users")
.Include("Countries")
.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()
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...