删除多对多实体框架

Posted

技术标签:

【中文标题】删除多对多实体框架【英文标题】:Removing many to many entity Framework 【发布时间】:2022-01-09 17:31:03 【问题描述】:

ArtistArtistType 之间存在多对多关系。我可以像下面这样轻松地添加艺术家ArtistType

foreach (var artistType in this._db.ArtistTypes
    .Where(artistType => vm.SelectedIds.Contains(artistType.ArtistTypeID)))

    artist.ArtistTypes.Add(artistType);


_db.ArtistDetails.Add(artist);
_db.SaveChanges();

这会使用正确的映射更新多对多关联表。但是当我尝试从表中删除任何项目时,我没有收到任何错误,但它没有从表中删除它?

foreach (var artistType in this._db.ArtistTypes
    .Where(at => vm.SelectedIds.Contains(at.ArtistTypeID)))

    artistDetail.ArtistTypes.Remove(artistType);


this._db.Entry(artistDetail).State = EntityState.Modified;
this._db.SaveChanges();

我错过了什么?

【问题讨论】:

【参考方案1】:

标准方法是从数据库中加载艺术家包括当前相关类型,然后从加载的类型集合中删除具有所选 ID 的类型。更改跟踪将识别哪些类型已被删除,并将正确的 DELETE 语句写入连接表:

var artist = this._db.Artists.Include(a => a.ArtistTypes)
    .SingleOrDefault(a => a.ArtistID == someArtistID);

if (artist != null)

    foreach (var artistType in artist.ArtistTypes
        .Where(at => vm.SelectedIds.Contains(at.ArtistTypeID)).ToList())
    
        artist.ArtistTypes.Remove(artistType);
    
    this._db.SaveChanges();        

【讨论】:

突然间,在这个答案的帮助下,我能够看到大局。非常感谢! 这不是浪费,因为当您真的只需要 id 时,您正在完全加载所有子 ArtistTypes。 是否可以只为给定的艺术家加载您关心的艺术家类型?我有一种情况,当我只想删除一个关联时,它可能会加载数千个“艺术家类型”。 如果您可以直接访问影子表(在 Artist 和 ArtistType 之间),您可以直接删除该条目。【参考方案2】:

为了删除只删除一个字段,我想出了这个解决方案。这看起来很奇怪,但在 EF 中,大多数事情还是很奇怪,因为我们试图根据 OOP 告诉 EF 数据库操作。

using (var db = new Context())

    //Create existing entities without fetch:
    var artist = new Artist()  ArtistID = _artistID ;
    var type = new Type()  TypeID = _typeID ;

    //Add one entity to other's list 
    //This is in memory, not connected.
    //So we do this because we try to tell EF that we want to remove this item
    //Without fetch, we should add it first in order to remove :)
    artist.ArtistTypes.Add(type);

    //Attach that entity which you add an item to its list:
    db.Artists.Attach(artist); 
    //It's now connected and recognized by EF as database operation

    //After attaching, remove that item from list and save db
    artist.ArtistTypes.Remove(type);
    db.SaveChanges();

就是这样!使用此解决方案,您不再获取连接表 ArtistTypes 的所有条目。

【讨论】:

以上是关于删除多对多实体框架的主要内容,如果未能解决你的问题,请参考以下文章

Remove() 不适用于实体框架中的多对多关系

实体框架:多对多插入重复

多对多关系实体框架核心db优先

实体框架多对多异常与继承

多对多(自相关)特定订单实体框架

JPA多对多删除实体