web-dev-qa-db-fra.com

Relation un à zéro avec Entity Framework Core 2.0

Je migre une bibliothèque Entity Framework 6.1.3 Code First vers Entity Framework Core avec C # et .NET Framework 4.7.

J'ai cherché sur Entity Framework Core avec Google, mais je n'ai pas trouvé beaucoup d'informations à ce sujet, j'ai donc essayé de le faire moi-même.

Sur Entity Framework 6.1.3, j'ai cette classe de configuration:

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

J'ai migré vers celui-ci:

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

Mais le constructeur n'a pas de méthode HasRequired, et je pense que les autres méthodes WithOptional, WithMany et WillCascadeOnDelete non plus.

J'ai migré vers cela, mais je ne sais pas si c'est 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);
        }

J'ai vérifié la documentation EntityTypeBuilder mais je ne sais pas quelles méthodes dois-je utiliser à la place ou si c'est la bonne façon de migrer vers Entity Framework Core.

Cette relation n'est pas de un à zéro:

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

Dans ce SO Answer dit que je dois mettre ForeignKey à null, il le définira comme facultatif, mais je ne peux pas définir Code.CodeId comme nullable.

9
VansFannel

La configuration EF6 crée une soi-disant One-to-One Shared Primary Key Association où le PK de l'entité dépendante est également un FK vers l'entité principale.

Les choses ont changé dans EF Core. Il prend naturellement en charge les associations univoque PK et FK partagées. Les options facultatives/obligatoires ne sont pas non plus utilisées pour déterminer les extrémités principale et dépendante de l'association. IsRequired est utilisé pour contrôler si l'entité dépendante peut exister sans principal et s'applique uniquement avec un FK séparé. Tandis que HasForeignKey et HasPrincipalKey sont utilisés pour déterminer les extrémités principale et dépendante de l'association et également mapper le FK dépendant et la clé PK/alternative principale.

Cela étant dit, la configuration EFC équivalente est la suivante:

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

Nous commençons donc par définir la relation à l'aide de HasOne + WithOne.

Puis HasForeignKey<AggregationChildren>(ag_ch => ag_ch.AggregationChildrenId) pour dire à EF que (1) AggregationChildren est la fin dépendante de la relation, et (2) que PK AggregationChildrenId doit également être utilisé comme FK.

Enfin, OnDelete(DeleteBehavior.Restrict) est l'équivalent EFC de l'EF6 WillCascadeOnDelete(false). Les autres options comme ClientSetNull et SetNull ne s'appliquent que lorsque la personne à charge a un FK optionnel séparé, ce qui n'est pas le cas avec l'association PK partagée.

Référence: Relations

15
Ivan Stoev