首页 > 解决方案 > Entity Framework Core 3.0 中的拥有类型问题

问题描述

我有 EF Core 3.0 preview4 的奇怪行为。我有主课:

public enum ClientType
{
    Customer = 0,
    Produces = 1,
}

public class User : IdentityUser<Guid>
{
    public ClientType ClientType { get; set; }
    public SMSCodeInfo SMSCodeInfo { get; set; }
    public string Discriminator { get; set; }
}

在此代码中 SMSCodeInfo 是一个类:

public class SMSCodeInfo
{ 
    public long Code { get; set; }
    public DateTime Expiration { get; set; }

    public SMSCodeInfo() { }
    public SMSCodeInfo(int days, int hours, int minutes) : this(DateTime.Now.AddDays(days).AddHours(hours).AddMinutes(minutes)) { }
    public SMSCodeInfo(DateTime Expiration)
    {
        this.Expiration = Expiration;
        Code = new Random().Next(100000, 999999);
    }        
}

我尝试通过不同的方法将SMSCodeInfo作为拥有的数据添加到类中:属性使用,在方法中添加代码:User[Owned]OnModelCreating(ModelBuilder modelBuilder)

modelBuilder.Entity<User>().OwnsOne(o => o.SMSCodeInfo);

但是每次我进行迁移时,我都会得到 2 个表:AspNetUsers一个关于用户的身份信息(我在我的项目中使用 Asp.net 核心身份)和AspNetUsers1一个由SMSCodeInfo成员组成的表。EF Core 生成此代码用于迁移,我无法理解“为什么”!

        migrationBuilder.CreateTable(
            name: "AspNetUsers1",
            columns: table => new
            {
                UserId = table.Column<Guid>(nullable: false),
                Code = table.Column<long>(nullable: false),
                Expiration = table.Column<DateTime>(nullable: false)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_AspNetUsers1", x => x.UserId);
                table.ForeignKey(
                    name: "FK_AspNetUsers1_AspNetUsers_UserId",
                    column: x => x.UserId,
                    principalTable: "AspNetUsers",
                    principalColumn: "Id",
                    onDelete: ReferentialAction.Cascade);
            });

“额外的”。我希望将拥有的数据添加到 AspNetUser 表中,而不是单独的表中。

PS 这个问题出现在从 IdentityUser<> 派生的类中。对于我的项目代码中的其他类,这样的modelBuilder.Entity<TOwner>().OwnsOne(o => o.ToBeOwned);工作正确,并提供具有注入拥有类型的正确表。

标签: c#entity-frameworkasp.net-core.net-core

解决方案


根据EF Core 中的 Owned Entity TypesmodelBuilder.Entity<User>().OwnsOne(o => o.SMSCodeInfo);应该[Owned]在表中创建实体列,Owner但奇怪的是它会创建一个具有奇怪名称的单独表AspNetUsers1

如果您希望[Owned]实体列应位于单独的表中,那么您的配置应如下所示:

modelBuilder.Entity<User>().OwnsOne(o => o.SMSCodeInfo , sm => 
{
   sm.ToTable("SMSCodeInfo");
});

它将生成如下:

migrationBuilder.CreateTable(
            name: "SMSCodeInfo",
            columns: table => new
            {
                UserId = table.Column<Guid>(nullable: false),
                Code = table.Column<long>(nullable: false),
                Expiration = table.Column<DateTime>(nullable: false)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_SMSCodeInfo", x => x.UserId);
                table.ForeignKey(
                    name: "FK_SMSCodeInfo_AspNetUsers_UserId",
                    column: x => x.UserId,
                    principalTable: "AspNetUsers",
                    principalColumn: "Id",
                    onDelete: ReferentialAction.Cascade);
            });

推荐阅读