【问题标题】: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();

我错过了什么?

【问题讨论】:

    标签: c# entity-framework many-to-many dbcontext


    【解决方案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 的所有条目。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-08
      相关资源
      最近更新 更多