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

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

问题描述

我正在使用 C# 和 .NET Framework 4.7 将 Entity Framework 6.1.3 Code First 库迁移到 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.

我一直在用 Google 搜索有关 Entity 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.

在实体框架 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);
        }
    }
}

但是builder没有HasRequired方法,我认为其他方法WithOptionalWithManyWillCascadeOnDelete> 要么.

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 文档,但我不知道我必须使用哪些方法,或者这是否是迁移到 Entity Framework Core 的正确方法.

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.

这种关系不是一对零:

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 也是对主体的 FK实体.

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 Core 中的情况发生了变化.它自然支持共享 PK 和 FK 一对一关联.也可选/必需不用于确定关联的主要端和从属端.IsRequired 用于控制依赖实体是否可以在没有主体的情况下存在并且仅适用于单独的 FK.而HasForeignKeyHasPrincipalKey用于确定关联的主端和从属端,同时映射从属FK和主体PK/Alternate Key.

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(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 WillCascadeOnDelete(false) 的 EFC 等效项.ClientSetNullSetNull 等其他选项仅在依赖项具有单独的可选 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天全站免登陆