web-dev-qa-db-ja.com

Entity Framework Core 2.0との1対ゼロの関係

Entity Framework 6.1.3のコードファーストライブラリを、C#および.NET Framework 4.7を備えたEntity Framework Coreに移行しています。

Entity Framework Core with 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);
        }
    }
}

私はこれに移行しました:

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

しかし、ビルダーにはHasRequiredメソッドがありません。他のメソッドWithOptionalWithManyおよび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);
        }

私は EntityTypeBuilder のドキュメントをチェックしてきましたが、代わりにどのメソッドを使用する必要があるのか​​、またはこれがEntity Framework Coreに移行する正しい方法であるのかわかりません。

この関係は1対0ではありません。

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

これで SO Answer は、ForeignKeyをnullに設定する必要があると述べましたが、オプションとして設定しますが、Code.CodeId null可能として。

9
VansFannel

EF6セットアップは、いわゆる One-to-One Shared Primary Key Association を作成します。ここで、依存エンティティのPKはプリンシパルエンティティへのFKでもあります。

EF Coreでは状況が変わりました。共有PKとFKの1対1の関連付けを自然にサポートします。また、optional/requiredは、関連付けの主目的と従属目的を決定するために使用されません。 IsRequiredは、依存エンティティがプリンシパルなしで存在できるかどうかを制御するために使用され、個別のFKでのみ適用されます。 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);
_

したがって、HasOne + WithOneを使用して関係を定義することから始めます。

次に、HasForeignKey<AggregationChildren>(ag_ch => ag_ch.AggregationChildrenId)を使用して、(1)AggregationChildrenが関係の従属端であること、および(2)PK AggregationChildrenIdもFKとして使用する必要があることをEFに通知します。

最後に、OnDelete(DeleteBehavior.Restrict)は、EF6のWillCascadeOnDelete(false)に相当するEFCです。 ClientSetNullSetNullなどの他のオプションは、依存型に別のオプションのFKがある場合にのみ適用されます。これは、共有PKアソシエーションの場合とは異なります。

参照: 関係

15
Ivan Stoev