0

Lors de la construction de la migration, je reçois l'erreur suivante:Entity Framework de base One-One autoréférencement relation ne

Impossible de déterminer la relation représentée par la navigation « Location.NorthLocation » de type 'emplacement. Configurez manuellement la relation ou ignorez cette propriété à partir du modèle.

L'entité Lieu:

public class Location 
{ 
    public Guid Id { get; set; } 

    public DateTime CreatedWhen { get; set; } 
    public string CreatedBy { get; set; } 
    public DateTime ModifiedWhen { get; set; } 
    public string ModifiedBy { get; set; } 

    public Guid? NorthLocationId { get; set; } 
    public virtual Location NorthLocation { get; set; } 

    public Guid? SouthLocationId { get; set; } 
    public virtual Location SouthLocation { get; set; } 

    public Guid? EastLocationId { get; set; } 
    public virtual Location EastLocation { get; set; } 

    public Guid? WestLocationId { get; set; } 
    public virtual Location WestLocation { get; set; } 

} 

La configuration du type:

public class MyContext : DbContext 
{ 
    public MyContext(DbContextOptions<MyContext> options) : base(options) 
    { 
    } 

    public DbSet<Location> Locations { get; set; } 

    protected override void OnModelCreating(ModelBuilder builder) 
    { 
     base.OnModelCreating(builder); 

     builder.Entity<T>().HasKey("Id"); 
     builder.Entity<T>().Property("Id").ValueGeneratedOnAdd(); 
     builder.Entity<T>().Property("CreatedWhen").HasDefaultValueSql("GETDATE()").ValueGeneratedOnAdd(); 
     builder.Entity<T>().Property("ModifiedWhen").IsRequired(); 
     builder.Entity<T>().Property("CreatedBy").HasMaxLength(50).IsRequired(); 
     builder.Entity<T>().Property("ModifiedBy").HasMaxLength(50).IsRequired(); 

     // Locations 
     builder.Entity<Location>().HasOne(x => x.NorthLocation).WithOne(x => x.SouthLocation).HasForeignKey(typeof(Location), "NorthLocationId").OnDelete(DeleteBehavior.SetNull); 
     builder.Entity<Location>().HasOne(x => x.SouthLocation).WithOne(x => x.NorthLocation).HasForeignKey(typeof(Location), "SouthLocationId").OnDelete(DeleteBehavior.SetNull); 
     builder.Entity<Location>().HasOne(x => x.EastLocation).WithOne(x => x.WestLocation).HasForeignKey(typeof(Location), "EastLocationId").OnDelete(DeleteBehavior.SetNull); 
     builder.Entity<Location>().HasOne(x => x.WestLocation).WithOne(x => x.EastLocation).HasForeignKey(typeof(Location), "WestLocationId").OnDelete(DeleteBehavior.SetNull); 
    } 

} 

Mon but est d'avoir une entité de localisation que les auto-références ses propres voisins du Nord/Sud/Est/Ouest. Est-ce que quelqu'un peut suggérer pourquoi je pourrais avoir cette erreur?

Répondre

0

Votre configuration de modèle est incorrecte car elle mappe chacune des propriétés de navigation deux fois. Par exemple. SouthLocation est mappé à la fois comme navigation inverse pour la clé étrangère NorthLocationId et comme navigation directe pour SouthLocationId.

Chaque propriété de navigation (à savoir NorthLocation, SouthLocation, EastLocation, WestLocation) ne peut être mis en correspondance avec une relation (par exemple à l'étranger sur la touche).

Si je supprime les 2ème et 4ème lignes de la partie de configuration de relation, le modèle semble être fonctionnel. En général, dans EF Core, nous essayons de faire face à une configuration conflictuelle en laissant la dernière configuration à gagner, mais cela a quelques limites et il est difficile d'anticiper ce qui peut arriver quand vous exécutez ce code. Certainement, en utilisant EF Core 2.0 preview1 sur SQL Server, j'ai une exception différente (une erreur de SQL Server, se plaignant des dépendances cycliques en cascade delte), il est donc possible que nous ayons amélioré la façon dont nous gérons ce scénario.

Voici le code:

using System; en utilisant Microsoft.EntityFrameworkCore; en utilisant Microsoft.EntityFrameworkCore.Metadata;

namespace ConsoleApp4 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      using (var db = new MyContext()) 
      { 
       db.Database.EnsureDeleted(); 
       db.Database.EnsureCreated(); 
      } 
     } 
    } 

    public class MyContext : DbContext 
    { 
     public DbSet<Location> Locations { get; set; } 
     protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 
     { 
      optionsBuilder.UseSqlServer(@"server=(localdb)\mssqllocaldb;database=hey;ConnectRetryCount=0"); 
     } 

     protected override void OnModelCreating(ModelBuilder modelBuilder) 
     { 
      modelBuilder.Entity<Location>().HasKey("Id"); 
      modelBuilder.Entity<Location>().Property("Id").ValueGeneratedOnAdd(); 
      modelBuilder.Entity<Location>().Property("CreatedWhen").HasDefaultValueSql("GETDATE()").ValueGeneratedOnAdd(); 
      modelBuilder.Entity<Location>().Property("ModifiedWhen").IsRequired(); 
      modelBuilder.Entity<Location>().Property("CreatedBy").HasMaxLength(50).IsRequired(); 
      modelBuilder.Entity<Location>().Property("ModifiedBy").HasMaxLength(50).IsRequired(); 
      modelBuilder.Entity<Location>().HasOne(x => x.NorthLocation).WithOne(x => x.SouthLocation).HasForeignKey(typeof(Location), "NorthLocationId").OnDelete(DeleteBehavior.Restrict); 
      modelBuilder.Entity<Location>().HasOne(x => x.EastLocation).WithOne(x => x.WestLocation).HasForeignKey(typeof(Location), "EastLocationId").OnDelete(DeleteBehavior.Restrict); 
     } 
    } 

    public class Location 
    { 
     public Guid Id { get; set; } 
     public DateTime CreatedWhen { get; set; } 
     public string CreatedBy { get; set; } 
     public DateTime ModifiedWhen { get; set; } 
     public string ModifiedBy { get; set; } 
     public Guid? NorthLocationId { get; set; } 
     public virtual Location NorthLocation { get; set; } 
     public Guid? SouthLocationId { get; set; } 
     public virtual Location SouthLocation { get; set; } 
     public Guid? EastLocationId { get; set; } 
     public virtual Location EastLocation { get; set; } 
     public Guid? WestLocationId { get; set; } 
     public virtual Location WestLocation { get; set; } 
    } 
} 
+0

Si ces deux lignes sont exclues, comment cela fonctionne-t-il avec la clé étrangère correspondante? Est-ce que ef est assez intelligent pour le comprendre et le peupler encore? – Hades

+0

Vous n'auriez qu'un seul FK dans la base de données pour chaque relation sud-nord et pour chaque relation est-ouest. Le choix de l'emplacement du FK (par exemple la rangée nord ou sud) est complètement arbitraire. Ceci est à son tour plus une question de conception de base de données relationnelle que la question EF Core. BTW, je ne l'ai pas encore mentionné, mais je ne suis pas sûr que le suivi des relations nord-sud et est-ouest est un bon moyen de modéliser les emplacements géographiquement distribués. – divega

+0

J'ai essayé de supprimer les deux lignes et il me renvoie toujours la même erreur. C'est pour une carte de l'espace pour un jeu de stratégie. Essentiellement, je veux avoir la capacité de «voyager» dans n'importe quelle direction. – Hades