繁体   English   中英

EF6 - 代码优先 - 如何正确处理从m:n关系中删除父条目

[英]EF6 - code-first - how to properly handle deleting a parent entry from an m:n relationship

我有一种情况,我有两个实体 - ItemGroupItem - 以am:n方式链接:

CREATE TABLE ItemGroup
(
    ItemGroupId INT IDENTITY(1,1) PRIMARY KEY CLUSTERED,
    ItemGroupName VARCHAR(50)
)

CREATE TABLE Item
(
    ItemId INT IDENTITY(1,1) PRIMARY KEY CLUSTERED,
    ItemName VARCHAR(50)
)

CREATE TABLE ItemGroup_Item
(
    ItemGroupId INT NOT NULL
        CONSTRAINT FK_ItemGroupItem_ItemGroup
        FOREIGN KEY REFERENCES dbo.ItemGroup(ItemGroupId),
    ItemId INT NOT NULL
        CONSTRAINT FK_ItemGroupItem_Item
        FOREIGN KEY REFERENCES dbo.Item(ItemId),

    CONSTRAINT PK_Itemgroup_Item
        PRIMARY KEY CLUSTERED(ItemGroupId, ItemId)
)

因此,在我的SQL Server数据库中,我有一个“链接”表,通过包含它们各自的主键来连接这两个实体。

当我将其重新设计为EF 6模型时,我得到了这两个类:

[Table("Item")]
public partial class Item
{
    public Item()
    {
        ItemGroup = new HashSet<ItemGroup>();
    }

    public int ItemId { get; set; }

    [StringLength(50)]
    public string ItemName { get; set; }

    public virtual ICollection<ItemGroup> ItemGroup { get; set; }
}

[Table("ItemGroup")]
public partial class ItemGroup
{
    public ItemGroup()
    {
        Item = new HashSet<Item>();
    }

    public int ItemGroupId { get; set; }

    [StringLength(50)]
    public string ItemGroupName { get; set; }

    public virtual ICollection<Item> Item { get; set; }
}

并且DbContext类包含这个流畅的设置:

public partial class ItemGroupModel : DbContext
{
    public ItemGroupModel() : base("name=ItemGroupConn")
    { }

    public virtual DbSet<Item> Item { get; set; }
    public virtual DbSet<ItemGroup> ItemGroup { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Item>()
            .Property(e => e.ItemName)
            .IsUnicode(false);

        modelBuilder.Entity<Item>()
            .HasMany(e => e.ItemGroup)
            .WithMany(e => e.Item)
            .Map(m => m.ToTable("ItemGroup_Item").MapLeftKey("ItemId").MapRightKey("ItemGroupId"));

        modelBuilder.Entity<ItemGroup>()
            .Property(e => e.ItemGroupName)
            .IsUnicode(false);
    }
}

当我尝试删除ItemGroup时,我的麻烦就开始了:

using(ItemGroupModel ctx = new ItemGroupModel())
{
    ItemGroup grp = ctx.ItemGroup.FirstOrDefault();

    ctx.ItemGroup.Remove(grp);
    ctx.SaveChanges();
}

在这种情况下,我想让EF做的是删除该“链接”表中的所有条目(未在EF中建模为单独的实体),然后删除ItemGroup本身中的条目。 在该项目Item 不能接触!

问题是:由于此链接表不是我的EF模型中的实际实体,我如何确保这些链接条目实际上被删除,而不是它们链接到的Item 所以我无法真正处理手动删除“子”条目 - 没有我可以访问的子条目....

我怎么能很好地处理这个? 有时它似乎工作 - 有时我得到一个异常,说DELETE语句与ItemGroup_Item中仍然存在的条目冲突....

如果有人偶然发现这个问题 - 这是解决方案:我需要在保存之前在ItemGroup对象的导航属性上调用.Clear()方法。 这会“断开连接”此ItemGroup链接的任何Item ,而不实际删除基础Item对象本身 - 只是连接表中的条目消失了:

using(ItemGroupModel ctx = new ItemGroupModel())
{
    ItemGroup grp = ctx.ItemGroup.FirstOrDefault();

    // call Item.Clear() to remove any entries in the navigation
    // property which translates into any entries in the junction table
    // in the underlying database
    grp.Item.Clear();

    ctx.ItemGroup.Remove(grp);
    ctx.SaveChanges();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM