EFCore删除引用的实体

时间:2019-05-01 15:02:31

标签: c# entity-framework-core

我在项目中有两个实体:SupplierFinishingItemProductOptionListItem

ProductOptionListItem通过导航属性引用另一个。

当我尝试创建1个引用ProductOptionListItem的{​​{1}}时,它将起作用并将该关系保存在数据库中。

但是,当我尝试创建2个或更多引用同一SupplierFinishingItem的{​​{1}}时,只有第一个实体将关系保存到数据库。其他的则用ProductOptionListItem引用保存。

我设法在最小的控制台应用程序中重现了它:

SupplierFinishingItem

运行此代码后得到的数据库如下:

enter image description here

如您所见,只有null有一个using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; namespace relationship_test { class Program { static void Main(string[] args) { using (var db = new DatabaseContext()) { var finishing = new SupplierFinishingItem { Name = "Finishing"}; db.Finishings.Add(finishing); db.SaveChanges(); db.Options.Add(new ProductOptionListItem { Name = "Option 1", SupplierFinishingItem = finishing }); db.Options.Add(new ProductOptionListItem { Name = "Option 2", SupplierFinishingItem = finishing }); db.Options.Add(new ProductOptionListItem { Name = "Option 3", SupplierFinishingItem = finishing }); db.SaveChanges(); } } } public class DatabaseContext : DbContext { public DbSet<ProductOptionListItem> Options { get; set; } public DbSet<SupplierFinishingItem> Finishings { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer( @"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=entity-test;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False"); } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<ProductOptionListItem>() .HasOne(p => p.SupplierFinishingItem) .WithMany(s => s.UsedBy) .HasForeignKey(p => p.SupplierFinishingItemId) .OnDelete(DeleteBehavior.Restrict); } } public class ProductOptionListItem { public Guid Id { get; set; } public string Name { get; set; } public Guid? SupplierFinishingItemId { get; set; } public SupplierFinishingItem SupplierFinishingItem { get; set; } } public class SupplierFinishingItem { private HashSet<ProductOptionListItem> _usedBy; public Guid Id { get; set; } public string Name { get; set; } public IEnumerable<ProductOptionListItem> UsedBy => _usedBy?.ToList(); } } ,另外两个是Option 1

我在这里想念什么?

1 个答案:

答案 0 :(得分:3)

此问题是由实现集合导航属性引起的:

public IEnumerable<ProductOptionListItem> UsedBy => _usedBy?.ToList();

从吸气剂中返回新列表实例以某种方式使EF Core导航属性修复程序代码混乱并产生上述效果(甚至在调用SaveChanges()之前)。

解决方案是修复该实现,使其在每次调用时都不会返回新列表(无论如何,这对于属性获取器来说都是不正确的做法),例如:

public IEnumerable<ProductOptionListItem> UsedBy => _usedBy ?? (_usedBy = new HashSet<ProductOptionListItem>());

或将EF Core配置为直接使用后备字段:

modelBuilder.Entity<ProductOptionListItem>()
    .HasOne(p => p.SupplierFinishingItem)
    .WithMany(s => s.UsedBy)
    .HasForeignKey(p => p.SupplierFinishingItemId)
    .OnDelete(DeleteBehavior.Restrict)
    .Metadata.PrincipalToDependent.SetPropertyAccessMode(PropertyAccessMode.Field); // <--