【发布时间】:2023-04-04 13:17:01
【问题描述】:
我遇到了 EntityFramework 的条目删除问题以及同一实体的多对多关系。考虑这个简单的例子:
实体:
public class UserEntity {
// ...
public virtual Collection<UserEntity> Friends { get; set; }
}
Fluent API 配置:
modelBuilder.Entity<UserEntity>()
.HasMany(u => u.Friends)
.WithMany()
.Map(m =>
{
m.MapLeftKey("UserId");
m.MapRightKey("FriendId");
m.ToTable("FriendshipRelation");
});
- 我说得对吗,不能在 Fluent API 中定义
Cascade Delete? -
删除
UserEntity(例如Foo)的最佳方法是什么?它现在找我,我要
ClearFoo的Friends集合,然后我必须加载所有其他UserEntities,其中包含Foo中的Foo,然后删除Foo从每个列表中,在我从Users中删除Foo之前。但这听起来太复杂了。 -
是否可以直接访问关系表,这样我就可以删除这样的条目
// Dummy code var query = dbCtx.Set("FriendshipRelation").Where(x => x.UserId == Foo.Id || x.FriendId == Foo.Id); dbCtx.Set("FriendshipRelation").RemoveRange(query);
谢谢!
更新01:
-
我知道这个问题的最佳解决方案是在我调用
SaveChanges之前执行原始sql语句:dbCtx.Database.ExecuteSqlCommand( "delete from dbo.FriendshipRelation where UserId = @id or FriendId = @id", new SqlParameter("id", Foo.Id));但是这样做的缺点是,如果
SaveChanges由于某种原因失败,FriendshipRelation已经被删除并且无法回滚。还是我错了?
【问题讨论】:
-
级联删除是在您的迁移中定义的,而不是在您的流利映射中。
-
@BenRobinson,嗯,据我所知,您可以使用
WillCascadeOnDelete方法在 Fluent API 中为many:one关系定义级联删除。 -
@BenRobinson 这很误导,当然可以在fluent API中配置级联删除
-
您的 sql 语句在您的 update1 中是否正常工作?我的意思是,如果您有 id=57 的朋友,而其他人有朋友 FriendId=57 和 id=11,而其他人(x 先生)也有 FriendId =11;那么当你写“从 dbo.FriendshipRelation 中删除 UserId = 57 或 FriendId = 57”时。 x先生有一个不存在的朋友。我说的对吗?
-
@Arashjo,实际上不是,如果我们删除 ID 为
57的用户。这意味着我们必须删除FriendshipRelation中与此 ID 的所有关系。这意味着,我们会删除所有与UserId = 57为好友的用户,以及与此用户与FriendId = 57的所有其他用户 关系。换句话说,我们删除了我所有的朋友,并删除了我是朋友的所有关系。
标签: c# entity-framework ef-code-first entity-framework-6 code-first