我收到错误:“实体对象无法被 IEntityChangeTracker 的多个实例引用。”使用 .net MVC2 和实体框架4

发布于 2024-10-10 05:19:33 字数 2455 浏览 0 评论 0原文

几天来我遇到了一个大问题,而且我是实体框架的初学者。 我有 2 个实体:群组和新闻。一个或多个组可以看到一条新闻。我使用两个存储库(newsRepository 和 groupsRepository)。

这是我的新闻创建方法:

    public ActionResult Create()
    {
        return View(new CreateNewsViewModel(new News()));
    }

    [HttpPost]
    public ActionResult Create(CreateNewsViewModel model)
    {
        model.news.CategoryId = Int32.Parse(Request.Form["news.CategoryId"]);

        if (ModelState.IsValid)
        {
            News news = new News();

            DateTime date = DateTime.Now;

            //AuthorId a recuperer
            news.AuthorId = 1;
            news.Title = IntranetTools.UppercaseFirst(model.news.Title.Trim());
            news.Content = model.news.Content;
            news.IsVisible = Request.Form["news.IsVisible"].Contains("true");
            news.CreateDate = date;
            news.PublicationDate = date;
            news.LastChangedDate = date;
            news.CategoryId = model.news.CategoryId;

            // Collection des groupes concernés
            foreach (var c in model.allGroups)
            {
                if (Request.Form["" + c.GroupId].Contains("true"))
                {
                    News.Groups.Add(c);
                }
            }

            _newsRepository.AddToNewsSet(news);
            _newsRepository.SaveChanges();

            return Redirect("/NewsAdmin/Index/");
        }
        return View(model);
    }

我说我的所有组都已创建。我只想插入组(由用户通过复选框选择)。在我的“CreateNewsViewModel”中,我创建了一个组列表,其中包含数据库中的所有现有组。我通过“foreach”循环在视图中获取列表,并为每个组创建一个复选框。

我在控制器中重复使用相同的列表来比较复选框是否已被选中。 对于每个“真实”值,我在我的新闻(刚刚创建)的组集合中添加组。

这样,我收到此错误消息:

“实体对象不能被 IEntityChangeTracker 的多个实例引用。”(位于 _newsRepository.AddToNewsSet(news) 行;)

我尝试了一些解决方案,但仍然不这样做不明白我该如何解决这个问题。

感谢所有


编辑

实际上,如果我明确使用两个上下文并将我的对象分离/附加到其他上下文,那就很好,我没有错误。

            ObjectContext context  = _newsRepository.Context;
            ObjectContext context2 = _groupsRepository.Context;

            foreach (var c in groups)
            {
                if (Request.Form["" + c.GroupId].Contains("true"))
                {
                    context2.Detach(c);
                    context.Attach(c);
                    news.Groups.Add(c);
                }
            }

我想使用 Ladislav Mrnka 的解决方案并使用依赖项注入(我使用 Ninject 框架)为我的存储库提供相同的 ObjectContext(在单个请求处理中)。 我理解这个概念,但不知道如何编码。

I have a big problem since some days and I’m a very beginner in the Entity Framework.
I have 2 entities : Group and News. A news is visible by one or many groups. I use two repositories (newsRepository and groupsRepository).

This is my Create method for the news :

    public ActionResult Create()
    {
        return View(new CreateNewsViewModel(new News()));
    }

    [HttpPost]
    public ActionResult Create(CreateNewsViewModel model)
    {
        model.news.CategoryId = Int32.Parse(Request.Form["news.CategoryId"]);

        if (ModelState.IsValid)
        {
            News news = new News();

            DateTime date = DateTime.Now;

            //AuthorId a recuperer
            news.AuthorId = 1;
            news.Title = IntranetTools.UppercaseFirst(model.news.Title.Trim());
            news.Content = model.news.Content;
            news.IsVisible = Request.Form["news.IsVisible"].Contains("true");
            news.CreateDate = date;
            news.PublicationDate = date;
            news.LastChangedDate = date;
            news.CategoryId = model.news.CategoryId;

            // Collection des groupes concernés
            foreach (var c in model.allGroups)
            {
                if (Request.Form["" + c.GroupId].Contains("true"))
                {
                    News.Groups.Add(c);
                }
            }

            _newsRepository.AddToNewsSet(news);
            _newsRepository.SaveChanges();

            return Redirect("/NewsAdmin/Index/");
        }
        return View(model);
    }

I say that all my groups are already created. I just want to insert the groups (chosen by the user via checkboxes). In my “CreateNewsViewModel”, I create a list of groups that contains all existing groups in my DB. I get the list in my view, via a “foreach” loop and create a checkbox for each group.

I reuse the same list in my controller to compare if checkboxes have been checked.
For each “true” value, I add groups in the groups collection of my news (just created).

With this, I get this Error Message :

“An entity object cannot be referenced by multiple instances of IEntityChangeTracker.” (at line _newsRepository.AddToNewsSet(news);)

I try some solutions but I still don’t understand how I can solve this problem.

Thanks for all


Edit

Actually, if I use explicitly two contexts and detach/attach my objects to other context it's fine and I have no erros.

            ObjectContext context  = _newsRepository.Context;
            ObjectContext context2 = _groupsRepository.Context;

            foreach (var c in groups)
            {
                if (Request.Form["" + c.GroupId].Contains("true"))
                {
                    context2.Detach(c);
                    context.Attach(c);
                    news.Groups.Add(c);
                }
            }

I would like to use the Ladislav Mrnka's solution and use the dependency injection (I use Ninject framework) to give the same ObjectContext to my repositories (in single request processing).
I understand the concept but I don't know how to code it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

靑春怀旧 2024-10-17 05:19:33

错误消息表明 News 对象或任何相关的 Group 对象附加到不同的 ObjectContext 实例。您的存储库是如何实现的以及如何获取 model.allGroups?如果您从具有自己的 ObjectContext 实例的 GroupsRepository 加载 allGroups,那么它可能是问题的根源。解决方案是:(

  • 首选)在单个请求处理中为所有存储库共享单个 ObjectContext
  • 从数据库加载对象时分离对象(ObjectContext 有 Detach 方法)
  • 从数据库加载对象时关闭 ObjectContext

The error message says that News object or any of related Group objects is attached to different ObjectContext instance. How is your repository implemented and how did you get model.allGroups? If you loaded allGroups from GroupsRepository which has its own ObjectContext instance then it is probably source of the problem. The solution would be:

  • (Preferred) Share single ObjectContext for all repositories in single request processing
  • Detach objects when you load them from database (ObjectContext has Detach method)
  • Close ObjectContext when you load objects from database
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文