与Entity Framework Core 2.0的一对零关系 [英] One-to-Zero relationship with Entity Framework Core 2.0

查看:110
本文介绍了与Entity Framework Core 2.0的一对零关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用C#和.NET Framework 4.7将Entity Framework 6.1.3代码优先库迁移到Entity Framework Core。

I'm migrating a Entity Framework 6.1.3 Code First library to Entity Framework Core with C# and .NET Framework 4.7.

我一直在搜索Entity带有Google的Framework Core,但是我没有找到很多有关它的信息,所以我尝试自己做。

I've been searching about Entity Framework Core with Google but I haven't found many information about it so I have try to do it by myself.

在Entity Framework 6.1.3上,我有此配置类:

On Entity Framework 6.1.3 I have this configuration class:

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);
        }
    }
}

我已经迁移到了这个:

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);
        }
    }
}

但是建设者还没有有必要方法,我认为其他方法 WithOptional WithMany WillCascadeOnDelete

But builder hasn't got HasRequired method, and I think the others methods WithOptional, WithMany and WillCascadeOnDelete either.

我已经迁移到了这个版本,但是我不确定它是否正确:

I have migrated to this, but I'm not sure if it is correct:

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);
        }

我一直在检查 EntityTypeBuilder 文档,但我不知道我必须使用哪种方法代替

I've been checking EntityTypeBuilder documentation but I don't know which methods do I have to use instead or if this is the right way to migrate to Entity Framework Core.

此关系不是一对零的关系:

This relationship is not one-to-zero:

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

在此 SO Answer 说,我必须将ForeignKey设置为null,它将其设置为可选,但我不能将 Code.CodeId 设置为可为空。

In this SO Answer said that I have to put ForeignKey to null it will set it as optional, but I can't set Code.CodeId as nullable.

推荐答案

EF6设置正在创建所谓的一对一共享主键关联,其中依赖实体的PK

The EF6 setup is creating a so called One-To-One Shared Primary Key Association where the PK of the dependent entity is also a FK to principal entity.

EF核心中的情况已经改变。它自然支持共享的PK和FK一对一关联。同样,不使用可选/必需来确定关联的主体和从属端。 IsRequired 用于控制从属实体是否可以不存在委托人而仅适用于单独的FK。 HasForeignKey HasPrincipalKey 用于确定关联的主体和从属端,并映射从属FK和主体PK /备用密钥。

The things have changed in EF Core. It supports naturally both shared PK and FK one-to-one associations. Also optional/required are not used to determine the principal and dependent ends of the association. IsRequired is used to control if the dependent entity can exists w/o principal and applies only whith separate FK. While HasForeignKey and HasPrincipalKey are used to determine the principal and dependent ends of the association and also map the dependent FK and principal PK / Alternate Key.

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

With that being said, the equivalent EFC configuration is as follows:

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

所以我们首先使用 HasOne + WithOne

So we start with defining the relationship using HasOne + WithOne.

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

Then HasForeignKey<AggregationChildren>(ag_ch => ag_ch.AggregationChildrenId) to tell EF that (1) AggregationChildren is the dependent end of the relationship, and (2) that the PK AggregationChildrenId should also be used as FK.

最后, OnDelete(DeleteBehavior.Restrict)是EF6的EFC等效项, WillCascadeOnDelete (假)。其他选项,例如 ClientSetNull SetNull 仅在依赖项具有单独的可选FK时适用,而在共享PK关联。

Finally, OnDelete(DeleteBehavior.Restrict) is the EFC equivalent of the EF6 WillCascadeOnDelete(false). The other options like ClientSetNull and SetNull apply only when the dependent has a separate optional FK, which is not the case with shared PK association.

参考:关系

这篇关于与Entity Framework Core 2.0的一对零关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆