26

Considérons deux classes.Équivalent pour .HasOptional dans Entity Framework Core 1 (EF7)

public class File 
{ 
    [Key] 
    public string Id { get; set; } 

    public string Message_Id { get; set; } 

    internal Message Message { get; set; } 
} 

public class Message 
{ 
    [Key] 
    public string Id { get; set; }  
} 

Dans EF6, pour la relation N: 1..0, il y avait cette API fluide.

modelBuilder.Entity<File>() 
      .HasOptional(e => e.Message).WithMany().HasForeignKey(e => e.Message_Id); 

Qu'est-ce qui est équivalent dans Entiity Framework Core 1?

Merci

Répondre

38

Vous ne trouverez pas une méthode équivalente à EF 7. Par convention, une propriété dont le type CLR peut contenir null sera configuré en option. Donc, que décider si la relation est facultative ou non est si la propriété FK est nullable ou non respectivement.

En résumé, en raison de votre Message_Id propriété FK est string, il accepte déjà la valeur null, donc si vous utilisez la configuration Api Fluent suivante:

modelBuilder.Entity<File>() 
      .HasOne(s => s.Message) 
      .WithMany() 
      .HasForeignKey(e => e.Message_Id) 

EF configurera votre relation en option (ou N: 0..1 comme demandé).

Dans le cas où votre propriété FK est de type valeur, comme int, vous devez la déclarer nulle (int?).

Aussi j'ai remarqué maintenant que vous avez une propriété de navigation avec modificateur d'accès internal. Vous devez toujours déclarer les propriétés de votre entité comme public.

+0

Juste pour ajouter une observation: EF configure également la relation que nécessaire étant donné un '[Obligatoire]' annotation sur la propriété, même si le type lui-même est annulable. – davidmdem

+0

Ne pense pas que ce soit vrai. EF6 et EF Core sont tous deux capables de représenter des relations 1: 0..1 comme EntityA.PK est une clé étrangère à EntityB.PK – shannon

+0

@shannon Jetez un coup d'oeil dans ce [link] (https://docs.microsoft.com/fr -us/ef/core/modeling/relations) et montrez-moi dans api couramment comment faire un 'HasOptional' sans faire ce que j'explique dans ma réponse – octavioccl

0

Dans EF de base, vous pouvez utiliser des moyens de remorquage pour relier les tables de remorquage:

  • intérieur OnModelCreating:

    protected override void OnModelCreating(ModelBuilder modelBuilder) 
    { 
        base.OnModelCreating(modelBuilder);    
    
        modelBuilder.Entity<File>() 
           .HasOne(c => c.Message) 
           .WithOne() 
           .HasForeignKey(c => c.MessageId)       
    } 
    
  • Créer une nouvelle classe FileConfiguration et de l'appeler à l'intérieur OnModelCreating:

    public class FileConfiguration : IEntityTypeConfiguration<File> 
    { 
        public void Configure(EntityTypeBuilder<File> builder) 
        {   
         builder.ToTable("File");    
    
         // Id 
         builder.HasKey(c => c.Id); 
         builder.Property(c => c.Id) 
           .ValueGeneratedOnAdd(); 
    
         // Message 
         builder.HasOne(c => c.Message) 
           .WithOne(c => c.File) 
           .HasForeignKey<Message>(c => c.MessageId) 
           .OnDelete(DeleteBehavior.Restrict); 
        } 
    } 
    

    et à l'intérieur OnModelCreating mis ci-dessous: codes

    protected override void OnModelCreating(ModelBuilder modelBuilder) 
    { 
        base.OnModelCreating(modelBuilder); 
    
        modelBuilder.ApplyConfiguration(new FileConfiguration());          
    }