我最近开始学习实体框架和OData,虽然有一个学习曲线,但大多数问题似乎可以在不寻求帮助的情况下解决。我遇到的这个问题困扰了我一天多,我在文档中找不到我要找的东西。
该项目是一个简单的电影数据库;电影有导演和演员,“电影专业人士”有电影的导演和演技。当我尝试删除电影时,我得到一个错误说:
“与处于已删除状态的实体添加关系是 不允许。“
或所有内容都运行而不会抛出错误,但是演员/导演的状态将恢复到删除调用之前的状态。
以下是我正在使用的代码:
protected IHttpActionResult OnDelete(int key)
{
if (!Initialized) return NotFound();
var entity = DeleteOperation(key, DbContext);
if (entity == null) return NotFound();
DbSet.Remove(entity);
DbContext.SaveChanges();
return StatusCode(HttpStatusCode.NoContent);
}
protected override Movie DeleteOperation(int key, MovieContext movieContext)
{
var removeMovie = movieContext.Movies.FirstOrDefault(key, true, "Cast", "Director");
if (removeMovie == null) return null;
if (removeMovie.Cast != null)
{
foreach (var actor in removeMovie.Cast)
{
actor.Actor =
movieContext.Movies.Any(m => m.Key != removeMovie.Key && m.Cast.Any(c => c.Key == actor.Key));
}
}
if (removeMovie.Director != null)
{
removeMovie.Director.Director =
movieContext.Movies.Any(m => m.Key != removeMovie.Key &&
m.Director.Key == removeMovie.Director.Key);
}
return movieContext.Movies.FirstOrDefault(key, false);
}
public static T FirstOrDefault<T>(this DbSet<T> dbset, int key, bool disableTracking, params string[] include)
where T : ModelBase
{
if (dbset == null) return null;
var query = disableTracking ? dbset.AsNoTracking() : dbset.AsQueryable();
if (include.Length <= 0) return query.FirstOrDefault(e => e.Key == key);
var i = 1;
try
{
for (i = 0; i < include.Length; i++)
{
query = query.Include(include[i]);
}
return query.FirstOrDefault(e => e.Key == key);
}
catch (Exception)
{
throw new Exception("Include value '" + include[i] + "' has no context");
}
}
我感觉演员/导演状态还原与我在数据库上下文中对.AsNoTracking()
的调用有关,但是没有这样做,我每次都会得到上述错误。根据我的理解,我需要基本上从Cast
实体中分离Director
和Movie
,但我不知道正确的语法。
答案 0 :(得分:0)
因此,我提出的解决方案是在using
语句中创建数据库上下文的新实例。问题是我使用DeleteOperation
的数据库上下文的相同实例,就像我在OnDelete
中一样。这清除了所有错误,让我将更改保存到实体。