C# 实体框架核心3.0中的拥有类型问题
我对EF Core 3.0 preview4有着奇怪的行为。 我有主课: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
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-thenmodelBuilder.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();
}