C# (实体框架)可以';即使禁用了延迟加载,也不能删除具有多对多关系的表
我确实对这个问题进行了广泛的研究,但由于项目的一些独特限制,没有一个答案是适用的 问题:C# (实体框架)可以';即使禁用了延迟加载,也不能删除具有多对多关系的表,c#,sql,asp.net,asp.net-mvc,ef-model-first,C#,Sql,Asp.net,Asp.net Mvc,Ef Model First,我确实对这个问题进行了广泛的研究,但由于项目的一些独特限制,没有一个答案是适用的 问题: public TEntity DeleteOne([FromUri] int id, [FromBody] TEntity entity) { try { if (id != entity.Id) throw new HttpResponseException(HttpStatusCode.BadRequest); Database.
public TEntity DeleteOne([FromUri] int id, [FromBody] TEntity entity)
{
try
{
if (id != entity.Id)
throw new HttpResponseException(HttpStatusCode.BadRequest);
Database.Entry(entity).State = EntityState.Deleted;
try
{
Database.SaveChanges();
return entity;
}
catch (DbUpdateConcurrencyException)
{
if (!EntityExists(id))
throw new HttpResponseException(HttpStatusCode.NotFound);
throw;
}
}
catch (Exception ex)
{
Log.e<ReadWriteController<TEntity, TDto, TPto>>(ex.ToJson());
throw;
}
}
我继承了第一款mvc应用程序,它拒绝删除具有多对多关系的表,因为EF自动创建的联接表中存在外键约束
例如:
注意事项:
public TEntity DeleteOne([FromUri] int id, [FromBody] TEntity entity)
{
try
{
if (id != entity.Id)
throw new HttpResponseException(HttpStatusCode.BadRequest);
Database.Entry(entity).State = EntityState.Deleted;
try
{
Database.SaveChanges();
return entity;
}
catch (DbUpdateConcurrencyException)
{
if (!EntityExists(id))
throw new HttpResponseException(HttpStatusCode.NotFound);
throw;
}
}
catch (Exception ex)
{
Log.e<ReadWriteController<TEntity, TDto, TPto>>(ex.ToJson());
throw;
}
}
如果我设置了一个断点,并单步执行删除代码并展开要删除的对象,则删除操作将正常进行。这让我相信这是延迟加载的问题。在我继续做得太远之前,下面是我修修补补之前的代码
违规代码:
public TEntity DeleteOne([FromUri] int id, [FromBody] TEntity entity)
{
try
{
if (id != entity.Id)
throw new HttpResponseException(HttpStatusCode.BadRequest);
Database.Entry(entity).State = EntityState.Deleted;
try
{
Database.SaveChanges();
return entity;
}
catch (DbUpdateConcurrencyException)
{
if (!EntityExists(id))
throw new HttpResponseException(HttpStatusCode.NotFound);
throw;
}
}
catch (Exception ex)
{
Log.e<ReadWriteController<TEntity, TDto, TPto>>(ex.ToJson());
throw;
}
}
2) 使用反射手动加载所有属性:
var queryable = Database.Set<TEntity>().AsQueryable();
var type = typeof(TEntity);
var properties = type.GetProperties();
foreach (var property in properties)
{
var isVirtual = property.GetGetMethod().IsVirtual;
if (isVirtual && properties.FirstOrDefault(c => c.Name == property.Name + "Id") != null)
{
queryable = queryable.Include(property.Name);
}
}
TEntity toDelete = queryable.Single(x => x.Id == id);
Database.Entry(toDelete).State = EntityState.Deleted;
var queryable=Database.Set().AsQueryable();
变量类型=类型(强度);
var properties=type.GetProperties();
foreach(属性中的var属性)
{
var isVirtual=property.getMethod().isVirtual;
if(isVirtual&&properties.FirstOrDefault(c=>c.Name==property.Name+“Id”)!=null)
{
queryable=queryable.Include(property.Name);
}
}
TEntity toDelete=queryable.Single(x=>x.Id==Id);
Database.Entry(toDelete).State=EntityState.Deleted;
3) 在删除之前附着对象以强制其跟踪:
Database.Set<TEntity>().Attach(entity);
Database.Set<TEntity>().Remove(entity);
Database.Set().Attach(实体);
Database.Set().Remove(实体);
不幸的是,这些方法都不能强制EF正确地删除该表,尽管据我所知,它应该删除。为什么使用断点并展开项允许它在其他方法不允许的情况下删除?plzz共享您的模型类通常EF自动创建的联接表具有来自源表的级联删除FK约束。由于某种原因,您的表被关闭,这导致了问题。@IvanStoev这听起来很有可能,因为我以前遇到过这个问题,我的解决方案是删除并重新创建表。是否有任何方法可以在不重新创建表的情况下重新启用这些约束?以防万一,您是否尝试过以下答案中的类似内容:Code First或edmx?plzz共享您的模型类通常EF自动创建的联接表已从源表中级联删除FK约束。由于某种原因,您的表被关闭,这导致了问题。@IvanStoev这听起来很有可能,因为我以前遇到过这个问题,我的解决方案是删除并重新创建表。有没有办法在不重新创建表的情况下重新启用这些约束?以防万一,您是否尝试过下面的答案:Code First或edmx?