use*_*745 6 entity-framework-5
实体A,B的关系是一对多,(A有很多B,B必须属于A).
我禁用lazy loading并加载A,B,如下所示:
dbContext.As.Load();
//**particaly load B**
dbContext.Bs.Where(predicateX).Load();
Run Code Online (Sandbox Code Playgroud)
我用的时候
dbContext.As.Remove(someA)
Run Code Online (Sandbox Code Playgroud)
要删除A,我会遇到以下错误消息
The relationship could not be changed because one or more of the foreign-key properties is non-nullable
相反,如果我使用:
//remove all B in someA
foreach(B b in someA.Bs.ToList())
{
dbContext.Bs.Remove(b);
}
dbContext.As.Remove(someA)
Run Code Online (Sandbox Code Playgroud)
一切都好.
有一个更好的方法吗?
编辑
我正在使用Database First并在数据库端添加B的外键约束(在删除级联上).
我认为"外键约束"恰好等于代码"OnModelCreating".但代码"dbContext.As.Remove(someA)"无法按预期工作.
当ABC级联一对多关系时,事情变得更糟.为了删除someA,你需要这样做
foreach(B b in someA.Bs.ToList())
{
foreach(C c in b.Cs.ToList())
{
dbContext.Cs.Remove(c);
}
dbContext.Bs.Remove(b);
}
dbContext.As.Remove(someA);
Run Code Online (Sandbox Code Playgroud)
解决了:
我首先使用数据库(sqlite)并在数据库端添加外键约束.
使用vs2012从sqlite数据库文件创建edmx,
vs2012未能设置关系的"on delete cascade"属性.
手动设置属性后,单个调用"dbContext.As.Remove(someA)"按预期工作!
遗憾的是,(实际上)实体框架中没有批处理支持,所以你会遇到foreach多个属性.您可能希望查看EntityFramework.Extended项目,该项目添加了各种批处理操作来整理这样的代码(以及提高性能).
如果您确定在删除A时始终要删除相关的B,则将此关系配置为使用"on delete cascade"行为.这意味着当删除父A时,它的所有子B也会被自动删除.如何做到这一点取决于您如何创建数据库.如果您使用Code First,它将是这样的:
public class MyContext : DbContext
{
public DbSet<A> As { get; set; }
public DbSet<B> Bs { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<A>()
.HasMany(a => a.Bs)
.WithRequired(b => b.A)
.WillCascadeOnDelete();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6729 次 |
| 最近记录: |