EF Core 5 - 多对多 - 删除
EF Core 5 - Many to Many - remove
我正在使用 EF Core 5 的新功能,我不必自己指定多对多 class,而是让它为 EF 本身指定。
我有一个简单的classes:
用户映射:
public class UserMap : IEntityTypeConfiguration<User>
{
public void Configure(EntityTypeBuilder<User> builder)
{
builder.HasKey(x => x.Id);
builder.HasMany(x => x.Favorites).WithMany(x => x.Followers);
}
}
public class RecipeProviderMap : IEntityTypeConfiguration<RecipeProvider>
{
public void Configure(EntityTypeBuilder<RecipeProvider> builder)
{
builder.HasKey(x => x.Id);
builder.HasMany(x => x.Followers).WithMany(x => x.Favorites);
}
}
当然还有每个 class 中的集合,例如:
public ICollection<User> Followers { get; set; }
public ICollection<RecipeProvider> Favorites { get; set; }
如果我想向 RecipeProvider 添加关注者 class 我会这样做:
var recipeProvider = await _dataProvider
.RecipeProviders
.Include(x => x.Followers)
.FirstOrDefaultAsync(x => x.Id == request.RecipeProviderId, cancellationToken);
if (recipeProvider == null)
return Unit.Value;
recipeProvider.AddAsFavorite(user);
_dataWriter.Update(recipeProvider);
await _dataWriter.SaveChangesAsync();
没有那行有要添加
_dataWriter.Update(recipeProvider);
所以上面的示例适用于添加,但我在删除时遇到问题,我尝试了很多不同的选项。提案看起来像:
var user = await
_dataProvider
.Users
.Include(x => x.Favorites)
.FirstOrDefaultAsync(x => x.Id == request.FollowerId, cancellationToken);
var provider = user.Favorites.FirstOrDefault(x => x.Id == request.RecipeProviderId);
user.Favorites.Remove(provider);
await _dataWriter.SaveChangesAsync();
以上代码不删除实体。我错过了什么吗?
我用你的代码做了一个类似的模型,但有书和标签。
var tag = dbCotnext.Find<Tag>(1);
var book = dbCotnext.Find<Book>(1);
tag.Books.Add(book);
dbCotnext.SaveChanges();
tag.Books.Remove(book);
dbCotnext.SaveChanges();
我在 SaveChanges 和数据库中的所有内容都按预期显示后放置了断点,在遇到第一个断点后我在 BookTag table 中看到了新实体,在我遇到第二个断点后它消失了。
但是,我在您的代码中看到一些警告。您正在使用两个上下文,一个用于读取 _dataProvider
,另一个用于写入 _dataWriter
。我认为如果你在 _dataProvider
上调用 SaveChanges
它会起作用,但你在 _dataWriter
上调用它,其中你从其他上下文加载的实体不会被跟踪。您可以显式地将其加载到 _dataWriter
,然后从集合中删除该元素,然后保存更改,这样 SaveChanges
就会按预期在 _dataWriter
.
上工作
总而言之,我认为 _dataWriter
没有跟踪由另一个上下文 _dataProvider
.
加载的实体的变化
我正在使用 EF Core 5 的新功能,我不必自己指定多对多 class,而是让它为 EF 本身指定。
我有一个简单的classes:
用户映射:
public class UserMap : IEntityTypeConfiguration<User>
{
public void Configure(EntityTypeBuilder<User> builder)
{
builder.HasKey(x => x.Id);
builder.HasMany(x => x.Favorites).WithMany(x => x.Followers);
}
}
public class RecipeProviderMap : IEntityTypeConfiguration<RecipeProvider>
{
public void Configure(EntityTypeBuilder<RecipeProvider> builder)
{
builder.HasKey(x => x.Id);
builder.HasMany(x => x.Followers).WithMany(x => x.Favorites);
}
}
当然还有每个 class 中的集合,例如:
public ICollection<User> Followers { get; set; }
public ICollection<RecipeProvider> Favorites { get; set; }
如果我想向 RecipeProvider 添加关注者 class 我会这样做:
var recipeProvider = await _dataProvider
.RecipeProviders
.Include(x => x.Followers)
.FirstOrDefaultAsync(x => x.Id == request.RecipeProviderId, cancellationToken);
if (recipeProvider == null)
return Unit.Value;
recipeProvider.AddAsFavorite(user);
_dataWriter.Update(recipeProvider);
await _dataWriter.SaveChangesAsync();
没有那行有要添加
_dataWriter.Update(recipeProvider);
所以上面的示例适用于添加,但我在删除时遇到问题,我尝试了很多不同的选项。提案看起来像:
var user = await
_dataProvider
.Users
.Include(x => x.Favorites)
.FirstOrDefaultAsync(x => x.Id == request.FollowerId, cancellationToken);
var provider = user.Favorites.FirstOrDefault(x => x.Id == request.RecipeProviderId);
user.Favorites.Remove(provider);
await _dataWriter.SaveChangesAsync();
以上代码不删除实体。我错过了什么吗?
我用你的代码做了一个类似的模型,但有书和标签。
var tag = dbCotnext.Find<Tag>(1);
var book = dbCotnext.Find<Book>(1);
tag.Books.Add(book);
dbCotnext.SaveChanges();
tag.Books.Remove(book);
dbCotnext.SaveChanges();
我在 SaveChanges 和数据库中的所有内容都按预期显示后放置了断点,在遇到第一个断点后我在 BookTag table 中看到了新实体,在我遇到第二个断点后它消失了。
但是,我在您的代码中看到一些警告。您正在使用两个上下文,一个用于读取 _dataProvider
,另一个用于写入 _dataWriter
。我认为如果你在 _dataProvider
上调用 SaveChanges
它会起作用,但你在 _dataWriter
上调用它,其中你从其他上下文加载的实体不会被跟踪。您可以显式地将其加载到 _dataWriter
,然后从集合中删除该元素,然后保存更改,这样 SaveChanges
就会按预期在 _dataWriter
.
总而言之,我认为 _dataWriter
没有跟踪由另一个上下文 _dataProvider
.