Ado.Net Entity: Объект не отображает связанные элементы (внешние ключи) - PullRequest
3 голосов
/ 14 апреля 2009

У меня есть простая схема базы данных: пользователь, учетная запись. Пользователь имеет отношение 1-ко-многим с Учетной записью.

Я создал модель данных сущности ado.net и могу создавать пользователей и учетные записи и даже связывать их вместе. В базе данных account.user_id правильно заполнен, поэтому теоретически я должен иметь возможность доступа к User.Account.ToList () в C # через сущность.

Однако, когда я пытаюсь получить доступ к User.Account.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...??

Что мне здесь не хватает ??

Ответы [ 3 ]

2 голосов
/ 14 апреля 2009

Для этого следует использовать метод ObjectQuery.Include . Ваш метод также работает, но приводит к дополнительному запросу.

В вашем примере вы получите

User user = db.User.Include("Account").First(u => u.id == 1);

Вы должны выяснить, является ли строка "Account" правильной. Обычно это должно быть с префиксом что-то вроде MyEntities. Это зависит от пространства имен ваших сущностей, но с небольшой пробой и ошибкой вы сможете понять это.

2 голосов
/ 14 апреля 2009

Да, это распространенная проблема, когда вы начинаете использовать платформу Entity - ни родительские, ни дочерние отношения не загружаются с отложенной загрузкой, поэтому вы должны загружать их явно. Если вы собираетесь разделить контекст объекта между классами / методами, вы можете проверить, загружены ли отношения уже:

например.

    if(!user.Account.IsLoaded)
        user.Account.Load();

Вы можете сделать это проще с помощью простого метода расширения:

public static class EntityExtensions
{
    public static void EnsureLoaded(this RelatedEnd relatedEnd)
    {
        if (!relatedEnd.IsLoaded)
            relatedEnd.Load();
    }
}

использование этого делает ваш вызов снова короче:

user.Account.EnsureLoaded();

И поскольку он использует RelatedEnd, который является общим для родительских и дочерних отношений в структуре сущностей, вы можете использовать это и для родительских ссылочных отношений - например,

account.UserReference.EnsureLoaded();

Как говорит rwwilden, если в этом случае вы всегда собираетесь загружать дочерние объекты с родителем, вы можете использовать функцию Включить, чтобы сделать вызов более эффективным и избежать дополнительного обращения к базе данных.

1 голос
/ 14 апреля 2009

Полагаю, мои знания немного маловаты. :)

Сначала необходимо явно загрузить соответствующие учетные записи.

user.Account.Load();

Теперь он отображается правильно.

...