Ado.Сетевая сущность :Объект не отображает связанные элементы (внешние ключи)
-
09-09-2019 - |
Вопрос
У меня есть простая схема базы данных:Пользователь, Учетная запись.Пользователь имеет отношение "1 ко многим" к учетной записи.
Я сгенерировал ado.net модель данных сущностей, и я могу создавать пользователей и учетные записи и даже связывать их вместе.В базе данных account.user_id заполнен правильно, поэтому теоретически я должен иметь возможность получить доступ к User.Учетная запись.ToList() в C# через entity.
Однако, когда я пытаюсь получить доступ к пользователю.Учетная запись.ToList() Я получаю нулевые результаты.
User user = db.User.First(U => U.id == 1);
List<Account> accounts = user.Account.ToList(); ##count = 0...
Когда я добавляю следующий код перед предыдущим кодом, он внезапно выдает мне правильное значение 2.
Account account1 = db.Account.First(A => A.id == 1);
Account account2 = db.Account.First(A => A.id == 2);
User user = db.User.First(U => U.id == 1);
List<Account> accounts = user.Account.ToList(); ##count = 2...??
Чего я здесь не понимаю??
Решение
Вы должны использовать Объектный запрос.Включить метод для этого.Ваш метод также работает, но приводит к дополнительному запросу.
В вашем примере вы бы получили
User user = db.User.Include("Account").First(u => u.id == 1);
Вы должны выяснить, является ли строка "Account"
является правильным.Обычно это должно начинаться с чего-то вроде MyEntities
.Это зависит от пространства имен ваших сущностей, но с помощью небольших проб и ошибок вы должны быть в состоянии разобраться в этом.
Другие советы
Да, это распространенная проблема при запуске Entity framework - ни родительские, ни дочерние отношения не загружаются с задержкой, поэтому вам приходится загружать их явно.Если вы собираетесь совместно использовать контекст объекта между классами / методами, вы можете захотеть проверить, загружена ли уже связь:
например ,
if(!user.Account.IsLoaded)
user.Account.Load();
Вы можете сделать это проще с помощью простого метода расширения:
public static class EntityExtensions
{
public static void EnsureLoaded(this RelatedEnd relatedEnd)
{
if (!relatedEnd.IsLoaded)
relatedEnd.Load();
}
}
использование этого снова делает ваш вызов load короче:
user.Account.EnsureLoaded();
И поскольку он использует RelatedEnd , который является общим для родительских и дочерних отношений в entity framework, вы можете использовать это и для родительских ссылочных отношений - например
account.UserReference.EnsureLoaded();
Как говорит rwwilden, если в этом случае вы всегда собираетесь загружать дочерние объекты вместе с родительскими, вы можете захотеть использовать Include, чтобы сделать вызов более эффективным и избежать дополнительного обращения к базе данных.
Я предполагаю, что мои знания немного ограничены рамками.:)
Сначала вам необходимо явно загрузить связанные учетные записи.
user.Account.Load();
Теперь он действительно отображается корректно.