Вернуть полное имя из другой таблицы в частичном представлении входа

Я использую основную идентификацию asp.net, но намеренно разделил информацию о пользователе в другую таблицу, которая связана через пользовательский класс приложения.

Как я могу получить доступ к этой информации из частичного представления входа в систему?

Другие ответы определяют только то, что нужно извлекать информацию из пользовательского класса приложения. то есть:

var personID = UserManager.GetUserAsync(User).Result.PersonID;

Где мне нужно что-то вроде:

var fullName = UserManager.GetUserAsync(User).Result.Person.FullName;

Я предполагаю, что код не загружает дочернюю таблицу, так как я получаю следующую ошибку в объекте Person:

'Object reference not set to an instance of an object.'

Остальная часть моего кода приведена ниже для справки.

Пользователь приложения:

  public class ApplicationUser : IdentityUser
    {
        [ForeignKey("Person")]
        public int PersonID { get; set; }

        public virtual Person Person { get; set; }    
    }

Класс человека

public class Person
{
    public int PersonID { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    [NotMapped]
    [Display(Name = "Full Name")]
    public string FullName
    {
        get { return LastName + ", " + FirstName; }
    }

    public string Address { get; set; }

    public ApplicationUser ApplicationUser { get; set; }

}

Частичный вход:

@using Microsoft.AspNetCore.Identity
@using Models;
@inject SignInManager<ApplicationUser> SignInManager
@inject UserManager<ApplicationUser> UserManager

<ul class="navbar-nav">
@if (SignInManager.IsSignedIn(User))
{
    <li class="nav-item">
        <a  class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">Hello @User.Identity?.Name!</a>
        @{
                var personResult = UserManager.GetUserAsync(User).Result;
                var fullName = personResult.Person.FullName;                
            }  
          
    </li>
    <li class="nav-item">
        <form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Page("/", new { area = "" })" method="post" >
            <button  type="submit" class="nav-link btn btn-link text-dark">Logout</button>
        </form>
    </li>
}
else
{
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Register">Register</a>
    </li>
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login">Login</a>
    </li>
}
</ul>

в чем проблема с вашим текущим кодом?

lets do it 21.11.2022 05:47

@viveknuna 'Object reference not set to an instance of an object.' На объекте Person. Я предполагаю, что это связано с тем, что таблица лиц не загружается в класс UserManager, и я не знаю, как это решить.

Reafidy 21.11.2022 06:38

проверьте возвращаемое значение GetUserAsync

lets do it 21.11.2022 06:40

@viveknuna Он правильно возвращает пользовательский объект. И я могу получить PersonID, но он не будет детализирован до объекта Person.

Reafidy 21.11.2022 06:42

у него есть Person как null?

lets do it 21.11.2022 06:44

@viveknuna Да Person имеет значение null.

Reafidy 21.11.2022 06:47

Тогда вам нужно проверить, почему это null

lets do it 21.11.2022 06:57

@viveknuna Это вся предпосылка моего вопроса, я подозреваю, что он нулевой, потому что класс UserManager по умолчанию не загружает дочерние таблицы. Так нужно ли его как-то продлевать? Я просто не знаю, как загрузить таблицу лиц.

Reafidy 21.11.2022 07:07
Шаблоны Angular PrimeNg
Шаблоны Angular PrimeNg
Как привнести проверку типов в наши шаблоны Angular, использующие компоненты библиотеки PrimeNg, и настроить их отображение с помощью встроенной...
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Если вы веб-разработчик (или хотите им стать), то вы наверняка гик и вам нравятся "Звездные войны". А как бы вы хотели, чтобы фоном для вашего...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Начала с розового дизайна
Начала с розового дизайна
Pink Design - это система дизайна Appwrite с открытым исходным кодом для создания последовательных и многократно используемых пользовательских...
Шлюз в PHP
Шлюз в PHP
API-шлюз (AG) - это сервер, который действует как единая точка входа для набора микросервисов.
14 Задание: Типы данных и структуры данных Python для DevOps
14 Задание: Типы данных и структуры данных Python для DevOps
проверить тип данных используемой переменной, мы можем просто написать: your_variable=100
0
8
74
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

_userManager.GetUserAsync(User) основан на EF Core, он не будет загружать связанные данные по умолчанию, вы можете попробовать отложенную загрузку в качестве документа

Я пробовал, как показано ниже в моем случае:

установил пакет:

Модели:

public class ApplicationUser : IdentityUser
{
    
    //you have to set the property virtual here
    public virtual Person Person { get; set; }
}

public class Person
{
    public int PersonID { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    [NotMapped]
    [Display(Name = "Full Name")]
    public string FullName
    {
        get { return LastName + ", " + FirstName; }
    }

    public string Address { get; set; }
    //you have to set the property virtual here
    public virtual ApplicationUser ApplicationUser { get; set; }

    public string ApplicationUserId { get; set; }

}

изменил коды, которые регистрируют dbcontext:

builder.Services.AddDbContext<IdentityLazyloadingContext>(options =>
{
    options.UseSqlServer(connectionString);
    options.UseLazyLoadingProxies();
});

Результат:

Спасибо за вашу помощь, я думаю, что понимаю нетерпеливую и явную загрузку и как ее использовать в обычном коде. Однако я пытаюсь отобразить имя пользователя из таблицы лиц в стандартном представлении _LoginPartial ядра asp.net, которое является частичным представлением без кода. Смотрите код, который я добавил.

Reafidy 21.11.2022 20:16

О, моя вина, вы можете попробовать отложенную загрузку, чтобы получить свойства навигации, я обновил свой ответ, пожалуйста, проверьте его.

Ruikai Feng 22.11.2022 06:22

Ответ от Ruikai Feng отмечен как ответ, так как он поставил меня на правильный путь. Однако в итоге я использовал ленивую загрузку без прокси-фреймворка следующим образом:

Ленивая загрузка

   public class ApplicationUser : IdentityUser
    {
        private Person _Person;

        public ApplicationUser()
        {
        }

        private ApplicationUser(Action<object, string> lazyLoader)
        {
            LazyLoader = lazyLoader;
        }

        private Action<object, string> LazyLoader { get; set; }

        [ForeignKey("Person")]
        public int PersonID { get; set; }

        public Person Person
        {
            get => LazyLoader.Load(this, ref _Person);
            set => _Person = value;
        }
    }

Расширение:

  public static class PocoLoadingExtensions
    {
        // Load function for Lazy Loading, used in Application User.

        public static TRelated Load<TRelated>(
            this Action<object, string> loader,
            object entity,
            ref TRelated navigationField,
            [CallerMemberName] string navigationName = null)
            where TRelated : class
        {
            loader?.Invoke(entity, navigationName);

            return navigationField;
        }
    }

Другие вопросы по теме