EF Core 2.0使用OwnOne配置Guid类型Id默认值时迁移报错求助
解决EF Core中拥有实体与主实体主键默认值冲突问题
你遇到的这个错误,核心原因是EF Core在处理**拥有实体(Owned Entity)**的时候,默认会把主实体Order的主键Id作为拥有实体Address的外键,并且将这个外键映射到同一个Id列上。但你给主实体的Id设置了HasDefaultValueSql("(newid())"),而拥有实体的外键(自动生成的OrderId)没有配置默认值,导致同一列被配置了两种不同的默认值规则,最终触发迁移错误。
下面是具体的修复方案,只需要修改你的配置代码即可:
方案一:保持同列映射,统一默认值规则
class OrderEntityTypeConfiguration : IEntityTypeConfiguration<Order> { public void Configure(EntityTypeBuilder<Order> orderConfiguration) { orderConfiguration.ToTable("orders", OrderingContext.DEFAULT_SCHEMA); orderConfiguration.HasKey(o => o.Id); orderConfiguration.Ignore(b => b.DomainEvents); orderConfiguration.Property(b => b.Id).HasDefaultValueSql<Guid>("(newid())"); // 显式配置拥有实体Address的外键,确保和主实体主键的默认值规则一致 orderConfiguration.OwnsOne(o => o.Address, addressConfig => { // 定义拥有实体的外键列,映射到Id列,并设置和主实体相同的默认值 addressConfig.Property<Guid>("OrderId") .HasColumnName("Id") .HasDefaultValueSql("(newid())"); // 建立拥有实体与主实体的关联关系 addressConfig.WithOwner().HasForeignKey("OrderId"); }); } }
方案二:使用单独外键列,避免列名冲突
如果你希望表结构更清晰,也可以让拥有实体的外键使用单独的列,彻底避免冲突:
class OrderEntityTypeConfiguration : IEntityTypeConfiguration<Order> { public void Configure(EntityTypeBuilder<Order> orderConfiguration) { orderConfiguration.ToTable("orders", OrderingContext.DEFAULT_SCHEMA); orderConfiguration.HasKey(o => o.Id); orderConfiguration.Ignore(b => b.DomainEvents); orderConfiguration.Property(b => b.Id).HasDefaultValueSql<Guid>("(newid())"); // 配置拥有实体使用单独的外键列,避免和主实体主键列冲突 orderConfiguration.OwnsOne(o => o.Address, addressConfig => { // 指定外键列名为OrderId,不需要设置默认值(因为它会关联主实体的Id) addressConfig.Property<Guid>("OrderId") .HasColumnName("OrderId"); // 建立关联,外键指向主实体的Id addressConfig.WithOwner().HasForeignKey("OrderId"); }); } }
修改完成后,重新执行dotnet ef migrations add InitialDatabase命令,应该就能正常生成迁移文件了。
内容的提问来源于stack exchange,提问作者Juong David
相关产品推荐
相关产品推荐

