与Entity Framework Core 2.0的一对多关系
我正在使用C#和.NET Framework 4.7将Entity Framework 6.1.3 Code First库迁移到Entity Framework Core。
我一直在搜索有关Google的Entity Framework Core,但我没有找到很多关于它的信息,所以我自己尝试了。
在Entity Framework 6.1.3上我有这个配置类:
using System.Data.Entity.ModelConfiguration; namespace MyProject.Data.SqlServer.Configurations { class AggregationChildrenConfiguration : EntityTypeConfiguration { public AggregationChildrenConfiguration() { HasKey(ag_ch => ag_ch.AggregationChildrenId); HasRequired(ag_ch => ag_ch.Aggregation) .WithMany(ag => ag.AggregationChildren) .HasForeignKey(ag_ch => ag_ch.AggregationId); HasRequired(ag_ch => ag_ch.Code) .WithOptional(c => c.AggregationChild) .WillCascadeOnDelete(false); } } }
我已迁移到这个:
using DataLibrary; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; namespace BusinessLibrary.Configurations { class AggregationChildrenConfiguration : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder builder) { builder.HasKey(ag_ch => ag_ch.AggregationChildrenId); builder.HasRequired(ag_ch => ag_ch.Aggregation) .WithMany(ag => ag.AggregationChildren) .HasForeignKey(ag_ch => ag_ch.AggregationId); builder.HasRequired(ag_ch => ag_ch.Code) .WithOptional(c => c.AggregationChild) .WillCascadeOnDelete(false); } } }
但是构建器没有HasRequired
方法,我认为其他方法WithOptional
, WithMany
和WillCascadeOnDelete
。
我已迁移到此,但我不确定它是否正确:
using DataLibrary; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using System; namespace BusinessLibrary.Configurations { class AggregationChildrenConfiguration : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder builder) { builder.HasKey(ag_ch => ag_ch.AggregationChildrenId); builder.HasOne(ag_ch => ag_ch.Aggregation) .WithMany(ag => ag.AggregationChildren) .HasForeignKey(ag_ch => ag_ch.AggregationId) .IsRequired(); builder.HasOne(ag_ch => ag_ch.Code) .WithOne(c => c.AggregationChild) .OnDelete(DeleteBehavior.SetNull); }
我一直在检查EntityTypeBuilder文档,但我不知道我必须使用哪些方法,或者这是迁移到Entity Framework Core的正确方法。
这种关系不是一对一的:
builder.HasOne(ag_ch => ag_ch.Code) .WithOne(c => c.AggregationChild) .OnDelete(DeleteBehavior.SetNull);
在这个SO答案说我必须将ForeignKey设置为null它将它设置为可选,但我不能将Code.CodeId
设置为可空。
EF6设置正在创建所谓的一对一共享主密钥关联 ,其中从属实体的PK也是主体实体的FK。
EF Core中的情况发生了变化。 它自然支持共享PK和FK一对一关联。 还可以使用optional / required来确定关联的主要和从属端。 IsRequired
用于控制依赖实体是否可以存在w / o principal并且仅适用于单独的FK。 HasForeignKey
和HasPrincipalKey
用于确定关联的主要和从属端,并映射依赖的FK和主要PK /备用密钥。
话虽如此,等效的EFC配置如下:
builder.HasOne(ag_ch => ag_ch.Code) .WithOne(c => c.AggregationChild) .HasForeignKey(ag_ch => ag_ch.AggregationChildrenId) .OnDelete(DeleteBehavior.Restrict);
因此,我们首先使用HasOne
+ WithOne
定义关系。
然后HasForeignKey
告诉EF(1) AggregationChildren
是关系的依赖端,(2)PK AggregationChildrenId
也应该用作FK。
最后, OnDelete(DeleteBehavior.Restrict)
是EFC等效的WillCascadeOnDelete(false)
。 ClientSetNull
和SetNull
等其他选项仅在依赖项具有单独的可选FK时应用,而不是共享PK关联的情况。
参考: 关系