我有一个名为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
来处理对同一个表的两个引用。
答案 0 :(得分:1)
你可以用下一个方式来做。首先,您应该为模型public virtual List<Item> ParentNextItems { get; set; }
和public virtual List<Item> ParentPreviousItems { get; set; }
添加两个新属性。所以你的模型将是这样的
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; }
}
而且你可以用下一种方式配置它
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)
更改并编写下一个模型:
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?),我在答案中做了相应的修改。
据我所知,你不能在一次.SaveChanges()
旅行中做到这一点。创建第二个项目时,您应该已将第一个项目保存到数据库中。 (无论如何这是另一个问题的主题)
但无论如何,如果你将代码修改为类似的东西
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();
您可以在一个transaction
中完成答案 1 :(得分:0)
您不需要拥有 Collection,因为据我所知,您的目标是创建某种类型的 Two Way LinkedList
。 A 能够通过向主模型添加 .HasOne()
来修复它。
modelBuilder.Entity<Item>().HasOne(x => x.NextItem);
modelBuilder.Entity<Item>().HasOne(x => x.PreviousItem);