【问题标题】:Extending IdentityUser not loading added fields扩展 IdentityUser 不加载添加的字段
【发布时间】:2020-04-07 15:39:52
【问题描述】:

我正在使用 Asp.Net 和 Microsoft Identity。我正在扩展 IdentityUser 以添加一些额外的信息。

我的 IdentityUser 覆盖:

using Microsoft.AspNetCore.Identity;

namespace DASBlazorSite.Data
{
    public class SiteUser : IdentityUser
    {
        public SiteUser() : base()
        {
        }

        public AspNetUserDetail UserData { get; set; }
    }
}

AspNetUserDetail:

using System;
using System.ComponentModel.DataAnnotations;

namespace DASBlazorSite.Data
{
    public class AspNetUserDetail
    {
        [Key]
        public Guid Id { get; set; }

        [StringLength(50)]
        public string FirstName { get; set; }

        [StringLength(50)]
        public string MiddleName { get; set; }

        [StringLength(50)]
        public string LastName { get; set; }
    }
}

完成添加迁移更新数据库之后,我看到正在创建 AspNetUserDetail 表。我还在 AspNetUsers 中看到了一个额外的列,UserDataId
当我修改用户并将其保存为UserManager.UpdateAsync(SiteUser) 时,我看到在 AspNetUsers 中填充了 GUID,在 AspNetUserDetail 中填充了匹配的 GUID。我还看到了在 AspNetUserDetail 中填充的 FirstName 等的相应值。
在这一点上,一切看起来都很好。但是,当我通过 UserManager 检索用户时,UserData 字段为空。
这是某种实体框架延迟/渴望加载的东西吗?关于我将如何着手纠正它的任何建议?
奇怪的是,如果我加载一个用户,然后将 null UserData 设置为 new AspNetUserDetail 并填写相应的值,然后执行 UserManager.UpdateAsync(SiteUser) 在 AspNetUserDetail 表中创建一个全新的条目。它有一个新的 GUID,UserDataId 字段现在指向它。 AspNetUserDetail 中的先前条目现在处于孤立状态。

【问题讨论】:

    标签: c# asp.net-core asp.net-identity


    【解决方案1】:

    永远不会自动加载相关实体。您必须使用Include 急切地加载它们或依赖延迟加载(默认情况下不启用,一般不建议使用)。这里的问题是UserManager 没有提供通过Include 发出连接的工具。您可以继续启用延迟加载,但这实际上会导致在访问属性时发出新查询。这可能会导致 N+1 查询问题,在执行诸如迭代之类的事情时,并且可能会迅速失控以绝对打击您的数据库。这就是为什么不建议使用延迟加载的原因:很难确保您正在有效地查询数据库,而且不明显。

    如果您处于需要在用户身上加载相关实体的情况下,最好的办法是直接使用上下文,而不是UserManager

    var user = await _context.Users.Include(x => x.AspNetUserDetail).SingleOrDefaultAsync(x => x.Id == userId);
    

    话虽如此,您正在创建一个不存在的问题。拥有可扩展用户实体的全部意义在于能够直接在该实体上添加额外数据。首先,您不应该使用这样的“配置文件”类。把名字、姓氏等属性直接放在SiteUser实体上,然后就什么都不需要加入了。

    【讨论】:

    • 我明白你关于“个人资料”类的观点。这只是一个临时演示。最后,我可能最终会添加 30-40 列用户数据。我曾希望仅在我必须进入并浏览数据库的时候将事情隔离开来,但是对于一对一的关系,按照您的建议进行操作可能会更好。
    • 您还应该评估实体上实际应该包含哪些内容,哪些内容应该只是声明。声明最适用于临时数据(例如 Facebook 身份验证令牌)或不适用于每个用户的东西。
    猜你喜欢
    • 2013-12-11
    • 1970-01-01
    • 1970-01-01
    • 2011-11-15
    • 2018-11-11
    • 2018-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多