从DbContext删除具有关系的对象 [英] Removing Objects With a Relationship from DbContext

查看:297
本文介绍了从DbContext删除具有关系的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近开始学习Entity Framework和OData,尽管有一个学习曲线,但大多数问题似乎都可以在不寻求帮助的情况下解决.这个问题困扰了我一天多,而我在文档中找不到想要的东西.

I recently started learning Entity Framework and OData, and while there has been a learning curve, most problems seemed possible to solve without asking for help. This problem that I have has stumped me for over a day and I cannot find in the documentation what I am looking for.

该项目是一个简单的电影数据库;电影有导演和演员,电影专业人士"则有电影的导演和表演功劳.但是,当我尝试删除电影时,出现错误消息:

The project is a simple Movie Database; Movies have a director and actors, and 'Film Professionals' have directing and acting credits for movies. When I try to delete a movie though, either I get an error saying:

添加与处于Deleted状态的实体的关系是 不允许."

"Adding a relationship with an entity which is in the Deleted state is not allowed."

或一切运行都不会引发错误,但是角色/导演的状态会恢复到删除调用之前的状态.

or everything runs without throwing an error, but the state of the actors/director are reverted back to where they were before the delete call.

这是我正在使用的代码:

Here is the code that I am working with:

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()的调用有关,但是如果不这样做,我每次都会遇到上述错误.据我了解,我实际上需要将CastDirectorMovie实体分离,但是我不知道正确的语法.

I have a feeling the actor/director state reverting back has to do with the call of .AsNoTracking() on my database context, but without doing that, I get the aforementioned error every time. From my understanding, I need to essentially detach both Cast and Director from the Movie entity, but I don't know the proper syntax.

推荐答案

所以我想到的解决方案是在using语句中创建数据库上下文的新实例.问题是我在DeleteOperation中使用的数据库上下文实例与在OnDelete中使用的相同.这样可以清除所有错误,让我将更改保存到实体中.

So the solution that I came up with was to create a new instance of the database context within a using statement. The problem was that I was using the same instance of the database context for the DeleteOperation as I was in the OnDelete. This cleared up all errors and let me save the changes to the entities.

这篇关于从DbContext删除具有关系的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆