与Entity Framework Core 2.0的一对多关系

Van*_*nel 9 c# entity-framework entity-framework-core

我正在使用C#和.NET Framework 4.7将Entity Framework 6.1.3 Code First库迁移到Entity Framework Core.

我一直在搜索有关Google的实体框架核心,但我没有找到很多关于它的信息,所以我试着自己做.

在Entity Framework 6.1.3上我有这个配置类:

using System.Data.Entity.ModelConfiguration;

namespace MyProject.Data.SqlServer.Configurations
{
    class AggregationChildrenConfiguration : EntityTypeConfiguration<AggregationChildren>
    {
        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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我已迁移到这个:

using DataLibrary;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace BusinessLibrary.Configurations
{
    class AggregationChildrenConfiguration : IEntityTypeConfiguration<AggregationChildren>
    {
        public void Configure(EntityTypeBuilder<AggregationChildren> 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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但是构建者没有HasRequired方法,我认为其他方法WithOptional,WithMany也是WillCascadeOnDelete.

我已迁移到此,但我不确定它是否正确:

using DataLibrary;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;

namespace BusinessLibrary.Configurations
{
    class AggregationChildrenConfiguration : IEntityTypeConfiguration<AggregationChildren>
    {
        public void Configure(EntityTypeBuilder<AggregationChildren> 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);
        }
Run Code Online (Sandbox Code Playgroud)

我一直在检查EntityTypeBuilder文档,但我不知道我必须使用哪些方法,或者这是迁移到Entity Framework Core的正确方法.

这种关系不是一对一的:

builder.HasOne(ag_ch => ag_ch.Code)
    .WithOne(c => c.AggregationChild)
    .OnDelete(DeleteBehavior.SetNull);
Run Code Online (Sandbox Code Playgroud)

在这个SO答案说我必须将ForeignKey设置为null它将它设置为可选,但我不能设置Code.CodeId为可空.

Iva*_*oev 16

EF6设置正在创建所谓的一对一共享主密钥关联,其中从属实体的PK也是主体实体的FK.

EF Core中的情况发生了变化.它自然支持共享PK和FK一对一关联.还可以使用optional/required来确定关联的主要和从属端.IsRequired用于控制依赖实体是否可以存在w/o主体并且仅适用于单独的FK.while HasForeignKeyHasPrincipalKey用于确定关联的主要和从属端,并映射依赖的FK和主要PK /备用密钥.

话虽如此,等效的EFC配置如下:

builder.HasOne(ag_ch => ag_ch.Code)
    .WithOne(c => c.AggregationChild)
    .HasForeignKey<AggregationChildren>(ag_ch => ag_ch.AggregationChildrenId)
    .OnDelete(DeleteBehavior.Restrict);
Run Code Online (Sandbox Code Playgroud)

所以我们从使用HasOne+ 定义关系开始WithOne.

然后HasForeignKey<AggregationChildren>(ag_ch => ag_ch.AggregationChildrenId)告诉EF(1)AggregationChildren是关系的依赖结束,(2)PK AggregationChildrenId也应该用作FK.

最后,OnDelete(DeleteBehavior.Restrict)EFC相当于EF6 WillCascadeOnDelete(false).其他选项仅在依赖项具有单独的可选FK时才适用ClientSetNullSetNull应用,而不是共享PK关联的情况.

参考:关系

  • 在这种情况下没有必要。只有具有单独 FK 的从属实体才可以具有可选或必需的。请参阅 `IsRequired` 方法的描述 - *“配置这是否是必需的关系(即外键属性是否可以指定为 null)。”*。EF6 针对不同目的使用可选/必需术语。在 EFC 中,默认情况下关系是可选的,除非您具有显式单独的不可空 FK 属性。 (2认同)