Как получить связанные данные от одного к одному, построенные EF Core? - PullRequest
0 голосов
/ 03 мая 2020

У меня есть класс модели, унаследованный от IdentityUser, который имеет отношение 1 к 1

public class CustomUser: IdentityUser
{
    public ExtendedUserData ExtendedData { get; set; }
}

И у меня есть класс модели ExtendedData:

public class ExtendedUserData
{
    public Guid Id { get; set; }

    public string LastName { get; set; }
    public string FirstName { get; set; }
    public string Contract { get; set; }
    public string ExtendedDataOfCustomUserId { get; set; }
    public CustomUser CustomUser { get; set; }
}

(сделано с помощью это учебное пособие по ядру EF )

Но, если я использую этот метод для получения данных

public ExtendedUserData GetExtendedUserDataById(Guid id)
{
    return context.ExtendedUserDatas
                  .FirstOrDefault(x => x.ExtendedDataOfCustomUserId == id.ToString());
}

Я пытаюсь сделать так

ExtendedUserData userData = new ExtendedUserData();
userData = GetExtendedUserDataById(id);
....
userData.CustomUser.Id;

ИЛИ

userData.CustomUser.UserName;

Я получаю ошибку. как NullRefExc

Как я могу получить связанные данные от ExtendedUserData (или mb CustomUser), используя отношение 1 к 1?

Я думаю об этом, но помимо этого я не сделал больше ничего не придумаете

public ExtendedUserData GetExtendedUserDataById(Guid id)
{
    ExtendedUserData ud = context.ExtendedUserDatas
                                 .FirstOrDefault(x => x.ExtendedDataOfCustomUserId == id.ToString());
    ud.CustomUser = context.CustomUsers
                           .FirstOrDefault(x => x.Id == id.ToString());
    return ud;
}

Может быть, это можно сделать правильнее или короче?

Спасибо за ваши ответы!

1 Ответ

0 голосов
/ 04 мая 2020

Если у вас уже есть пользовательский пользователь, загруженный и отслеженный EF, это должно работать. Если у вас есть только удостоверение личности, вы должны позаботиться о связанных данных самостоятельно. Несколько способов:

Использовать готовую загрузку

public ExtendedUserData GetExtendedUserDataById(Guid id)
{
    return context.ExtendedUserDatas
                  .Include(x => x.CustomUser)
                  .FirstOrDefault(x => x.ExtendedDataOfCustomUserId == id.ToString())
                  ;
}

хорошо, если вы знаете, что каждый потребитель захочет загрузить CustomUser. В общем коде сложно сказать, что нужно включить заранее (CustomUser также может иметь связанные сущности, которые вы, возможно, захотите загрузить и т. Д., Что приводит к длинной цепочке .Include(...).ThenInclude(...)).

Используйте явное loading

public ExtendedUserData GetExtendedUserDataById(Guid id)
{
    var user = context.ExtendedUserDatas
                  .FirstOrDefault(x => x.ExtendedDataOfCustomUserId == id.ToString())
                   ;
    if (user != null)
    {
        context.Entry(user).Reference(x => x.CustomUser).Load();
    }
    return user;
}

Это не имеет особого смысла, как написано. Но так как каждый может это сделать, таким образом вы можете передать ответственность за загрузку связанных данных потребителю, который лучше знает, что ему нужно. В некотором роде писать неприятно, когда цепочка отношений становится длиннее и включает коллекции.

Существует также ленивая загрузка, которая скрывает всю эту сложность, но вам нужно предпринять некоторые шаги, чтобы активировать ее, и производительность легко убить с помощью это если ты забудешь, что это там. Больше информации обо всех трех: https://docs.microsoft.com/en-us/ef/core/querying/related-data#lazy - загрузка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...