I did search extensively on this issue, but because of some unique constraints on the project, none of answers were applicable.
ISSUE:
I inherited a model-first mvc app that's refusing to delete tables that have many-to-many relations because of foreign key constraints in the join table that EF automatically creates.
Example:
{"The DELETE statement conflicted with the REFERENCE constraint \"FK_ModuleImages_Module\". The conflict occurred in database \"CMS\", table \"dbo.ModuleImages\", column 'Modules_Id'.\r\nThe statement has been terminated."}
Caveat:
If I set a break point, and step through the delete code and expand out the object to be deleted, the delete proceeds fine. Which leads me to believe this is an issue with lazy loading. Before I proceed too much farther, here's the code as it stands before my tinkering.
Offending Code:
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;
}
}
Things I Have Tried
1) Disabling lazy loading completely:
Database.Configuration.LazyLoadingEnabled = false;
2) Using reflection to manually load all properties:
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;
3) Attaching the object right before deletions to force it to track:
Database.Set<TEntity>().Attach(entity);
Database.Set<TEntity>().Remove(entity);
Unfortunately, none of these approaches forces EF to properly delete the table, even though from everything I understand, it should. Why does using a breakpoint and expanding the item allow it to delete when these other methods don't?