1

次の項目と前の項目を参照するItemというクラスがあります。エンティティフレームワークコア自己参照表

public class Item 
{ 
    private Item() { } 

    public Item(string itemName) 
    { 
     ItemId = Guid.NewGuid(); 
     ItemName = itemName; 
    } 

    public Guid ItemId { get; set; } 
    public string ItemName { get; set; } 

    public Guid NextItemId { get; set; } 
    public virtual Item NextItem { get; set; } 

    public Guid PreviousItemId { get; set; } 
    public virtual Item PreviousItem { get; set; } 

    public Guid GroupId { get; set; } 
    public virtual Group Group { get; set; } 
} 

私は別のテーブルGroupを持っています。これはアイテムをグループ化するためのものです。

public class Group 
{ 
    private Group() { } 
    public Group(string groupName) 
    { 
     GroupId = Guid.NewGuid(); 
     GroupName = groupName; 
     GroupItems = new List<Item>(); 
    } 

    public void AddGroupItem(Item item) 
    { 
     if (Items.Count == 0) 
     { 
      Items.Add(item); 
     } 
     else 
     { 
      item.PreviousItem = Items.Last(); 
      item.PreviousItemId = Items.Last().ItemId; 
      Items.Last().NextItem = item; 
      Items.Last().NextItemId = item.ItemId; 

      Items.Add(item); 
     } 

    } 

    public Guid GroupId { get; set; } 
    public string GroupName { get; set; } 
    public virtual IList<GroupItem> GroupItems { get; set; } 
} 

アイテムとそのグループを作成して保存する方法は次のとおりです。

Group group1 = new Group("first group"); 
Item item1 = new Item("item 1"); 
Item item2 = new Item("item 2"); 
Item item3 = new Item("item 3"); 

group1.AddItem(item1); 
group1.AddItem(item2); 
group1.AddItem(item3); 

_context.Add(group1); 
_context.SaveChanges(); 

OnModelCreatingを使用して、同じテーブルへの2つの参照を処理するにはどうすればよいですか。

答えて

1

次のようにすることができます。まず、public virtual List<Item> ParentNextItems { get; set; }public virtual List<Item> ParentPreviousItems { get; set; }という2つの新しいプロパティをモデルに追加する必要があります。だからあなたのモデルは、この

public class Item 
{ 
    private Item() { } 

    public Item(string itemName) 
    { 
     ItemId = Guid.NewGuid(); 
     ItemName = itemName; 
    } 

    public Guid ItemId { get; set; } 
    public string ItemName { get; set; } 

    public Guid? NextItemId { get; set; } 
    public virtual Item NextItem { get; set; } 
    public virtual List<Item> ParentNextItems { get; set; } 

    public Guid? PreviousItemId { get; set; } 
    public virtual Item PreviousItem { get; set; } 
    public virtual List<Item> ParentPreviousItems { get; set; } 
} 

そして、あなたは、次の方法で、すべてのthats

protected override void OnModelCreating(ModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<Item>() 
     .HasKey(x => x.ItemId); 
    modelBuilder.Entity<Item>() 
     .HasOne(x => x.NextItem).WithMany(x => x.ParentNextItems).HasForeignKey(x => x.NextItemId) 
     .Metadata.DeleteBehavior = DeleteBehavior.Restrict; 
    modelBuilder.Entity<Item>() 
     .HasOne(x => x.PreviousItem).WithMany(x => x.ParentPreviousItems).HasForeignKey(x => x.PreviousItemId) 
     .Metadata.DeleteBehavior = DeleteBehavior.Restrict; 


    base.OnModelCreating(modelBuilder); 
} 

を、それを構成することができますよりのようなものになります。あなたがvoid OnModelCreating(ModelBuilder modelBuilder)変更をスキップして、ちょうど次のモデルを記述することができるよりも、あなたは属性の設定と同じachiaveしたいなら: 更新

public class Item 
{ 
    private Item() { } 

    public Item(string itemName) 
    { 
     ItemId = Guid.NewGuid(); 
     ItemName = itemName; 
    } 

    [Key] 
    public Guid ItemId { get; set; } 
    public string ItemName { get; set; } 

    public Guid? NextItemId { get; set; } 

    [ForeignKey(nameof(NextItemId))] 
    [InverseProperty(nameof(ParentNextItems))] 
    public virtual Item NextItem { get; set; } 

    [ForeignKey(nameof(NextItemId))] 
    public virtual List<Item> ParentNextItems { get; set; } 

    public Guid? PreviousItemId { get; set; } 
    [ForeignKey(nameof(PreviousItemId))] 
    [InverseProperty(nameof(ParentPreviousItems))] 
    public virtual Item PreviousItem { get; set; } 
    [ForeignKey(nameof(PreviousItemId))] 
    public virtual List<Item> ParentPreviousItems { get; set; } 
} 

また、あなたがPreviousItemId、NextItemIdはオプション(?GUID)を行う必要があり、私が対応しました私の答えが変わります。

私が知っている限り、あなたはちょうど1つでそれをすることができません.SaveChanges()旅行。 2番目のアイテムを作成するときは、すでにデータベースに保存されている最初のアイテムが必要です。ときに私は「System.InvalidOperationExceptionが」を取得

しかし、いずれにせよ、あなたがその

Group group1 = new Group("first group"); 
_context.Add(group1); 
Item item1 = new Item("item 1"); 
group1.AddItem(item1); 
_context.SaveChanges(); 
Item item2 = new Item("item 2"); 
group1.AddItem(item2); 
_context.SaveChanges(); 
Item item3 = new Item("item 3"); 
group1.AddItem(item3); 
_context.SaveChanges(); 

ような何かにあなたのコードを変更する場合は、1 transaction

+0

でそれを行うことができます(とにかく、これは別の質問のための主題です)アイテム '{' PreviousItemId '} - 'アイテム '{' ItemId '}、'アイテム '{' NextItemId '} - 'アイテム '{' ItemId '}'アイテム '{' NextItemId '} - >'アイテム '{' ItemId '}。 – Bryan

+0

私はその使用法を含め、より詳細な質問に追加しました。 – Bryan

+0

私は自分の答えを更新しました – YuriyP