如何使用IdentityUser创建两个差异表

时间:2019-05-14 13:58:19

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

在核心2.2中进行项目

我有两个继承$('#SelectPhone option') .hide() .filter([value=('#PhoneType').val() + '.' + ('#AllPhoneFeature').val()]) .show(); $("#SelectPhone").val([]); 的类 首先

IdentityUser

第二个

 public class DeveloperModel : IdentityUser
{
    [Required(AllowEmptyStrings = false)]
    public string FirstName { get; set; }

    [Required(AllowEmptyStrings = false)]
    public string SecondName { get; set; }

    [Required(AllowEmptyStrings = false)]
    public string Company { get; set; }

    [Required(AllowEmptyStrings = false)]
    public string CompanyName { get; set; }

    [Required(AllowEmptyStrings = false)]
    public string CompanyAdress { get; set; }

    [Required(AllowEmptyStrings = false)]
    public string CompanyEmail { get; set; }

    [Required(AllowEmptyStrings = false)]
    public string CompanyPhoneNumber { get; set; }
}

这两个课程的背景

public class UserModel : IdentityUser
{
    [Required(AllowEmptyStrings = false)]
    public string FirstName { get; set; }

    [Required(AllowEmptyStrings = false)]
    public string SecondName { get; set; }

}

,在迁移结束时,我接受了

 public class EFDbContext : IdentityDbContext
{
    public EFDbContext(DbContextOptions<EFDbContext> options) : base(options)
    {

    }

    public DbSet<UserModel> UserModels { get; set; }
    public DbSet<DeveloperModel> DeveloperModels { get; set; }
}

我用**标记来显示问题,在.Net继承的通常规则中,我为这两个类取了一张表。但是,我可以为每个类创建两个带有identityUser属性的表。

对于我的任务,我需要两个表。我不知道如何实现我的想法

1 个答案:

答案 0 :(得分:1)

我认为您必须将IdentityDbContext注入自定义模型。

您可以将模型映射到相应的表。 example

builder.Entity<UserModel>(b =>
{
    // Primary key
    b.HasKey(u => u.Id);

    //map properties
    b.Property(u => u.FirstName ).HasName("FirstName").IsUnique();
    b.Property(u => u.SecondName ).HasName("SecondName");

    // Maps to the AspNetUsers table
    b.ToTable("AspNetUsers");

});

builder.Entity<UserModelSplit>(b =>
{
    // Primary key
    b.HasKey(u => u.Id);

     //map properties
    b.Property(u => u.UserName ).HasName("UserName").IsUnique();
    b.Property(u => u.NormalizedUserName ).HasName("NormalizedUserName");
...
...
...
    // Maps to the AspNetUsers table
    b.ToTable("AspNetUsersSplit");

});
public class EFDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, string>  
    {  
        public EFDbContext (DbContextOptions<EFDbContext > options) : base(options)  
        {  

        }  
    }  

示例

public class ApplicationUser : IdentityUser

public class Instructor : ApplicationUser

public class Student : ApplicationUser

默认情况下,Entity Framework将为ApplicationUser创建一个表,并向其中添加一个Discriminator列。该列将具有三个可能的值之一:“ ApplicationUser”,“ Instructor”和“ Student”。当EF从该表中读取数据时,它将使用此列来实例化正确的类。这就是所谓的单表继承(STI)或按表层次结构(TPH)。这种方法的主要缺点是所有类的所有属性必须在同一张表上表示。例如,如果您要创建一个新的Student,则讲师的列仍将保留在记录中,只有那些值的值为空或默认值。这也意味着您不能在数据库级别上对诸如Instructor之类的东西强制执行属性,因为这将阻止保存无法提供这些值的ApplicationUser和Student实例。换句话说,派生类上的所有属性都必须为空。但是,您仍然可以始终使用视图模型来强制执行诸如表单所需的属性之类的事情。

如果您确实希望拥有单独的表,则可以通过将继承策略更改为所谓的每类型表(TPT)来在某种程度上实现该目标。这将为ApplicationUser保留表,但添加两个附加表,每个表分别用于Instructor和Student。但是,所有核心属性,外键等都将在ApplicationUser的表上,因为在那里定义了这些属性。 Instructor和Student的表将仅容纳在那些类(如果有)上定义的属性,以及ApplicationUser的表的外键。查询时,EF将执行联接以从所有这些表中引入数据,并使用适当的数据实例化适当的类。一些纯粹主义者更喜欢这种方法,因为它将数据标准化在数据库中。但是,由于连接的缘故,它在查询方面肯定很重。

最后一句警告,因为这会使人们不停地处理与身份继承有关的问题。 UserManager类是通用类(UserManager)。例如,AccountController中的默认实例是UserManager的实例。因此,如果您使用该实例,则从查询返回的所有用户将都是ApplicationUser实例,而不管Discriminator列的值如何。要获取Instructor实例,您需要实例化UserManager并将其用于与Instructor相关的查询。

Identity in an ASP.NET Core project