C# 实体框架核心3.0中的拥有类型问题

C# 实体框架核心3.0中的拥有类型问题,c#,entity-framework,asp.net-core,.net-core,C#,Entity Framework,Asp.net Core,.net Core,我对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; } pu

我对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
作为拥有的数据添加到
User
类中:
[owned]
属性用法,在
OnModelCreating(ModelBuilder ModelBuilder)
方法中添加代码:

modelBuilder.Entity<User>().OwnsOne(o => o.SMSCodeInfo);
“附加”。我希望将拥有的数据添加到AspNetUser表中,而不是单独的表中

另外,这个问题出现在从IdentityUser派生的类中。对于我的项目代码中的其他类,如
modelBuilder.Entity().OwnsOne(o=>o.ToBeOwned)工作正常,并使用注入的自有类型给出正确的表。

根据,
modelBuilder.Entity().OwnsOne(o=>o.SMSCodeInfo)
应在
所有者
表中创建
[Owned]
实体列,但应使用奇怪的名称
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);
            });
modelBuilder.Entity().OwnsOne(o=>o.SMSCodeInfo,sm=>
{
sm.ToTable(“SMSCodeInfo”);
});
它将产生如下结果:

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);
            });
migrationBuilder.CreateTable(
名称:“SMSCodeInfo”,
列:表=>new
{
UserId=table.Column(可空:false),
代码=table.Column(可空:false),
Expiration=table.Column(可空:false)
},
约束:表=>
{
表.PrimaryKey(“PK_SMSCodeInfo”,x=>x.UserId);
表1.外键(
名称:“FK_SMSCodeInfo_AspNetUsers_UserId”,
列:x=>x.UserId,
原则性:“AspNetUsers”,
主栏:“Id”,
onDelete:引用。级联);
});

也许对其他人也有帮助。由于使用efcore v2.2.6时出现相同的症状,因此刚登录到此页面。在主题上,建议在类上添加[Owned]属性应该足以获得“表共享/拆分”功能

我的设置:

[Owned]
public class Audit {
    public string By {get; set;}
    public DateTime At {get;set;}
}

public class Organisation {
    public Guid Id {get;set;}
    public Audit Created {get;set;}
    // other properties omitted 
}
我的数据库模式

CREATE TABLE Organisations (
   Id char(36),   -- I'm using MySQL8
   Created_At DateTime NOT NULL,
   Created_By varchar(32) NOT NULL,
   PRIMARY KEY Id
)
运行我的示例时,我得到以下消息:

InvalidOperationException:实体类型“Audit”要求定义主键

这似乎表明efcore正试图在一个单独的表中定位审计数据。我最后做的是在DbContext类中添加额外的配置,如@Dmitry所述,诀窍是指定表:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<Organisation>().OwnsOne(org => org.Created, created => created.ToTable("Organisation"));
    }
因此,您只需添加:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    modelBuilder.FixOwnedAttributeImplementation();
}

我希望将其添加到AspNetUsers表中,而不是单独的表中。@dmitry-then
modelBuilder.Entity().OwnsOne(o=>o.SMSCodeInfo)应该已经足够了,正如我在回答中所说的。您能检查一下是否有其他配置在这里进行干预吗?那么,这是一个bug?Unbehavior定义?这是一个我想要的解决方案,但没有什么变化:
sm.ToTable(“SMSCodeInfo”)应更改为
sm.ToTable(“AspNetUsers”)。非常感谢。很高兴看到你想出了一个解决办法。虽然它应该在没有sm.ToTable(“AspNetUsers”)的情况下自动完成。顺便说一句,祝你好运。随着对efcore 3.1的更新,扩展方法失败了,唯一的例外是没有定义AsNavigation()。作为一种解决方法,您可以直接使用property.Name。
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    modelBuilder.FixOwnedAttributeImplementation();
}