EF 4.1数据库优先方法。
假设我有这个表模式
用户1--M用户角色M--1角色
在外键中设置级联删除
UserRoles表有其他列,如CreatedDate,因此我为UserRoles创建了一个模型并进行了相应的映射。
我最终得到了以下型号:
User
----
int Id
string Name
List<UserRoles> UserRoles
UserRoles
---------
int UserId
int RoleId
DateTime CreatedDate
User User
Role Role
Role
----
int Id
string Name
List<UserRoles> UserRoles
如果我的配置正确,我应该能够删除用户吗?是否可以在不必手动清除UserRoles集合的情况下删除用户角色行?
所以我可以这样做吗:
DbContext.Entry(user).State = EntityState.Deleted;
DbContext.SaveChanges();
或者我必须这样做:
user.UserRoles.Clear();
DbContext.Entry(user).State = EntityState.Deleted;
DbContext.SaveChanges();
我的测试显示我必须清除子集合,但我发现有冲突的信息,即如果我正确地设置了级联删除,它应该只删除用户。
当我不清除用户角色时,我会收到此错误:
无法更改关系,因为外键属性是不可为null的
感谢您帮助澄清这一点!
您必须使用
DbContext.Users.Remove(user);
这与将状态设置为Deleted
不是一回事。设置状态不会将级联删除设置的任何子对象标记为Deleted
,但Remove
会标记。
将状态设置为Deleted
应该有效IF上下文中没有加载子项,因为EF将只向数据库发送父项的DELETE语句,并且由于数据库中的级联删除,数据库也将删除子项。
IF但是您已经将子项加载到上下文中,将父项上的状态设置为Deleted
不会设置子项的状态。EF会抛出异常,不是数据库在抱怨。
您应该能够指定删除角色或用户将依次删除子授予。您可以在fluent DbModelBuilder API上使用WillCascadeOnDelete()方法:
modelBuilder.Entity<UserRoles>
.HasRequired(d => d.User)
.WithMany(p => p.UserRoles)
.HasForeignKey(d => d.UserId)
.WillCascadeOnDelete();
modelBuilder.Entity<Role>
.HasMany(p => p.UserRoles)
.WithRequired(d => d.Role)
.HasForeignKey(d => d.RoleId)
.WillCascadeOnDelete();
使用此设置,删除用户或角色也应删除所有用户角色。