0

を失敗:Entity Frameworkのコアワンワン自己参照関係が

タイプ「場所」のナビゲーションプロパティ「Location.NorthLocation」で表さ関係を決定することができません。リレーションシップを手動で構成するか、モデルからこのプロパティを無視します。

場所エンティティ:

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

} 

タイプの構成:

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

} 

私の目標は、それが/北に自分の隣人の自己言及という場所エンティティを持つことです南/東/西。

なぜこのエラーが発生する可能性がありますか?

答えて

0

各ナビゲーションプロパティを2回マッピングするため、モデルの設定が正しくありません。例えば。 SouthLocationは、NorthLocationId外部キーの逆方向ナビゲーションとして、またSouthLocationIdの直接ナビゲーションとしてマッピングされます。

各ナビゲーションプロパティ(NorthLocationSouthLocationEastLocationWestLocation)は、1つの関係(つまり外部キー)にのみマッピングできます。

リレーションシップ設定部分の2行目と4行目を削除すると、モデルが機能しているようです。

一般的にEFコアでは、最後の設定でwinを実行させることによって競合する構成に対処しようとしていますが、これにはいくつかの制限があり、このコードを実行すると何が起こるかを予測することは困難です。確かに、SQL Serverに対してEF Core 2.0 preview1を使用すると、私は別の例外(SQL Serverのエラーフォーム、カスケードdelteの循環依存について不平を言います)を得ました。ここで

はコードです:システムを使用して

。 Microsoft.EntityFrameworkCoreを使用しています。 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

これらの2行が除外されている場合、それは対応する外部キーとどのように機能しますか? efはそれを把握してまだ入力していますか? – Hades

+0

あなたは実際には南北と東西の関係ごとにデータベースに1つのFKしか持たないでしょう。 FK(例えば、北または南列のいずれか)の位置を選択することは完全に任意である。これは、EF Coreの質問よりも、リレーショナルデータベースの設計に関する質問のほうが多くなります。ところで、これまで言及したことはありませんが、南北関係と東西関係を把握することは、実際に地理的に分散した場所をモデル化する良い方法であるとは確信していません。 – divega

+0

私は2行を削除しようとしても、それは私のために同じエラーをスローします。戦略ゲームのためのスペースマップです。基本的には、どの方向にも「移動する」能力が必要です。 – Hades