[英]Entity Framework: removing a relationship is not working
在我的多人游戏中,玩家的库存中有很多物品。 其中一些是块项目。 玩家库存中的方块物品也可以分配给“插槽”(用于游戏中的快速插槽系统)。
我拥有实体类的方式如下:我有一个PlayerContext
类型的实体,它有一个Inventory
实体。 Inventory
实体扩展了具有许多ItemContainer
实体的ItemContext
实体。 BlockItem
实体扩展了ItemContext
实体。 PlayerContext
还具有“槽”,它们是对BlockItem
实体的外键引用。
我在更改“插槽”时遇到问题。 我可以将BlockItem
分配给一个插槽,并将其保存在数据库中。 但是我无法从插槽中删除BlockItem
。 我试图通过设置slot = null
然后更新PlayerContext
来做到这一点。 新分配的BlockItem
保存为外键,但我尝试清除的插槽未保存,并且仍然具有对BlockItem
的引用。
在代码中,这看起来像:
class ChunkContext : DbContext
{
...
public DbSet<PlayerContext> Players { get; set; }
public DbSet<ItemContext> Items { get; set; }
public DbSet<BlockItem> blockItems { get; set; }
public DbSet<ItemContainerContext> ItemContainers { get; set; }
public DbSet<Inventory> Inventories { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder options) => options.UseSqlite("Data Source=../chunks.db");
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
...
modelBuilder.Entity<PlayerContext>().HasOne(p => p.inventory);
modelBuilder.Entity<ItemContext>().HasKey(i => i.id);
modelBuilder.Entity<ItemContext>().HasOne(i => i.container).WithMany(ic => ic.items);
...
modelBuilder.Entity<ItemContainerContext>().HasKey(ic => ic.id);
modelBuilder.Entity<ItemContainerContext>().HasMany(ic => ic.items).WithOne(item => item.container);
base.OnModelCreating(modelBuilder);
}
...
}
[Index(nameof(username), IsUnique = true)]
public class PlayerContext
{
public PlayerContext() { }
[Key]
public int id { get; set; }
...
[Required]
public Inventory inventory { get; set; }
// resource slots. this is digusting and I'm sorry
public BlockItem slot0 { get; set; }
public BlockItem slot1 { get; set; }
public BlockItem slot2 { get; set; }
public BlockItem slot3 { get; set; }
public BlockItem slot4 { get; set; }
public BlockItem slot5 { get; set; }
public BlockItem slot6 { get; set; }
public BlockItem slot7 { get; set; }
internal void SetResourceSelectorSlot(int slotIndex, int itemId)
{
using (var db = new ChunkContext())
{
if (slotIndex == 0) slot0 = inventory.FindItem(itemId) as BlockItem;
else if (slot0 != null && slot0.id == itemId) slot0 = null;
if (slotIndex == 1) slot1 = inventory.FindItem(itemId) as BlockItem;
else if (slot1 != null && slot1.id == itemId) slot1 = null;
if (slotIndex == 2) slot2 = inventory.FindItem(itemId) as BlockItem;
else if (slot2 != null && slot2.id == itemId) slot2 = null;
if (slotIndex == 3) slot3 = inventory.FindItem(itemId) as BlockItem;
else if (slot3 != null && slot3.id == itemId) slot3 = null;
if (slotIndex == 4) slot4 = inventory.FindItem(itemId) as BlockItem;
else if (slot4 != null && slot4.id == itemId) slot4 = null;
if (slotIndex == 5) slot5 = inventory.FindItem(itemId) as BlockItem;
else if (slot5 != null && slot5.id == itemId) slot5 = null;
if (slotIndex == 6) slot6 = inventory.FindItem(itemId) as BlockItem;
else if (slot6 != null && slot6.id == itemId) slot6 = null;
if (slotIndex == 7) slot7 = inventory.FindItem(itemId) as BlockItem;
else if (slot7 != null && slot7.id == itemId) slot7 = null;
db.Players.Update(this);
db.SaveChanges();
}
}
}
public class ItemContext
{
[Key]
public int id { get; set; }
public ItemContainerContext container { get; set; }
...
}
public class BlockItem : ItemContext
{
...
}
SetResourceSelectorSlot
已成功设置并保存项目的外键引用。 但是当我将它设置为 null 时,它并没有清除该字段。 当我将它设置为 null 时,它在数据库中根本没有改变。 我不想删除它引用的BlockItem
(因为它仍在玩家的库存中)。 我只想在数据库中将该字段设置为 NULL。 该字段可为空,默认为 null。 但是我所做的任何事情都无法在设置后将其改回为 null。 另外我将字段设置为 null 并且可以在调试时确认。 但是该更改不会传播到数据库。
添加这一行:
db.Entry(this).Reference(p => p.slot0).IsModified = true;
在我将该字段设置为 null 后,确保它保存在数据库中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.