在实体框架中删除子对象的正确方法

时间:2015-09-12 00:51:43

标签: c# entity-framework

我有函数,它接受Scene对象并添加它,如果没有带有这样的Id的场景或在另一种情况下更新它:

public void AddOrUpdateScene(Scene scene)
{
    using (var dbContext = new QuestContext())
    {
        if (scene.Id == 0)
        {
            dbContext.Scenes.Add(scene);
        }
        else
        {
            dbContext.Entry(scene).State = EntityState.Modified;
        }

        foreach (var answer in scene.AnswerChildren)
        {
            if (answer.Id == 0)
            {
                dbContext.Answers.Add(answer);
            }
            else
            {
                dbContext.Entry(answer).State = EntityState.Modified;
            }
        }
        dbContext.Quests.First(x => x.Id == scene.QuestId).DateModified = DateTime.Now;
        dbContext.SaveChanges(); 
    }
}

问题是在此代码中删除Answers。 让我们说我的数据库中有3个答案,其中id为1,2和3,附加到我的场景,ID为== 1。 如果传递给我的函数的场景具有id为1和2的答案,那意味着我必须从我的数据库中删除Id == 3的答案,所以我以这种方式编辑了代码:

public void AddOrUpdateScene(Scene scene)
        {
            using (var dbContext = new QuestContext())
            {
                dbContext.Configuration.ProxyCreationEnabled = false;
                var allAnswers = dbContext.Answers.AsNoTracking().Where(x => x.ParentSceneId == scene.Id).ToList();
                var ids = new List<int>();
                var answersToDelete = new List<Answer>();
                foreach (var answer in allAnswers.Where(answer => !scene.AnswerChildren.Select(x => x.Id).Contains(answer.Id)))
                {
                    ids.Add(answer.Id);
                    answersToDelete.Add(answer);
                    scene.AnswerChildren.Add(answer);
                }

                if (scene.Id == 0)
                {
                    dbContext.Scenes.Add(scene);
                }
                else
                {
                    dbContext.Entry(scene).State = EntityState.Modified;
                }

                foreach (var answer in scene.AnswerChildren)
                {
                    if (answer.Id == 0)
                    {
                        dbContext.Answers.Add(answer);
                    }
                    else
                    {
                        if (ids.Contains(answer.Id))
                        {
                            dbContext.Answers.Attach(answer);
                        }
                        else
                        {
                            dbContext.Entry(answer).State = EntityState.Modified;
                        }
                    }
                }

                dbContext.Answers.RemoveRange(answersToDelete);


                dbContext.Quests.First(x => x.Id == scene.QuestId).DateModified = DateTime.Now;
                dbContext.SaveChanges(); 
            }
        }

这段代码的作用与indended相同,但我想知道这是实现删除答案的最佳方式,假设我无法改变场景设计或传递给我的函数的方式吗?

0 个答案:

没有答案