使用EF Core删除子项

时间:2018-11-01 20:45:58

标签: c# entity-framework entity-framework-core ef-core-2.1

我已经查看了几个有关从EF Core的子集合中删除项目的类似问题,并且大多数都没有与EF Core相关的接受或答案:

https://stackoverflow.com/a/51349007 https://stackoverflow.com/a/49679247

我有一个叫做“相册”的类,以及一个叫做“音乐家”的属性。

当我使用EF从数据库中加载专辑时,我会包含Musicians属性,以便EF已经跟踪了该集合。如果我将一个项目添加到“音乐家”列表中并将更改保存在“唱片集”实体上,我会注意到它已添加到“音乐家和唱片集”的联结表中,并且效果很好。对于删除,这似乎没有效果。

示例:

var albums = repository.LoadAlbumsWithMusicians();
var musicians = CreateNewMusiciansForAlbumOne();

var test = albums.First().Musicians;
test.Clear();    
test.AddRange(musicians); 

使用此代码,如果音乐家的复合主键(MusicianIdMusicianTypeAlbumId)与EF已经知道的组合主键匹配,即使它实际上是不同的对象,它将知道该关系已存在,因此不会执行任何操作。这就是我的期望。

如果主键与现有键不匹配,则它将被视为集合中的新对象,并将新行添加到数据库中。这也是我的期望。

但是,我似乎无法做任何事情来使EF识别出应该删除集合中先前的项目,并且这些项目已被删除。在EF6中,我仅使用.Clear()和.AddRange()来处理这些关系,而EF则处理子关系的插入和删除。如建议的答案https://stackoverflow.com/a/49679247所示,如果没有从上下文中显式删除这些对象,如何确保已从数据库中删除这些已删除的子项?

1 个答案:

答案 0 :(得分:0)

使用下面的示例,可以说我们的“ selectedAppender”包含ID记录和所有联结表数据。为了添加项目和从该联结表中删除项目,我们要做的就是在一个单独的对象(删除和添加对象)中对其进行说明。

一旦我们有了要删除的项目列表,就像调用“删除”方法一样简单。

让我知道这是否还不够清楚。希望它会有所帮助。

file_appender selectedAppender = context.file_appender.Find(dto.Id);

int[] ids = dto.Loggers.Where(x => !x.Selected).Select(x => x.Id).ToArray();
var loggers_to_delete = selectedAppender.logger.Where(x => ids.Contains(x.id));
loggers_to_delete.ToList().ForEach(x =>
{
    selectedAppender.logger.Remove(x);
});

ids = dto.Loggers.Where(x => x.Selected).Select(x => x.Id).ToArray();
var loggers_to_add = context.logger.Where(x => ids.Contains(x.id));
loggers_to_add.ToList().ForEach(x =>
{
    selectedAppender.logger.Add(x);
});

linq的一个缺点是您必须迭代解决这些类型的问题。我没有办法进行批量删除。如果您知道一种方法并且可以改进它,请分享。