【问题标题】:Adding to EntityCollection adds to the end of collection in Entity Framework?添加到 EntityCollection 添加到实体框架中集合的末尾?
【发布时间】:2011-02-28 22:14:36
【问题描述】:

我正在尝试创建一个视图,用户可以在其中添加项目而无需转到新视图(该场景是一种 CV 网站,用户可以在其中添加有关工作经验、技能等的信息,去一个新的视图添加每个小东西似乎很荒谬)。

所以我有一个编辑视图,它显示了已添加项目的多个文本框,如果用户添加项目,则有一个 ajax 调用可以转到一个方法来获取新的集合。

以下是有问题的方法:

    public ActionResult Edit(int id)
    {
        Consultant consultant = _repository.GetConsultant(id);
        var vm = GetViewModel(consultant);
        return View(vm);
    }

    private DetailsViewModel GetViewModel(Consultant consultant)
    {
        return new DetailsViewModel
        {
            Programs = consultant.Programs.ToList(),
            Consultant = consultant
        };
    }
    public ActionResult NewProgram(int id)
    {
        //TODO: ordering is rather strange, because the entitycollection adds at the beginning rather than the end...
        Consultant consultant = _repository.GetConsultant(id);
        consultant.Programs.Add(new Program()); 
        _repository.Save();
        var vm = GetViewModel(consultant);
        return PartialView("ProgramList", vm);
    }

现在问题是:当调用 NewProgram 方法时,它会向 Consultant 对象添加一个新程序并创建一个新的 ViewModel 以发送回,但是它将新程序添加到 EntityCollection 的开头,而不是结尾.但是,当您发布整个表单并再次打开编辑视图时,列表会将新添加的程序放在最后。这很奇怪。用户会认为他/她在列表的开头添加了一个项目,但如果他们再次返回页面,他们会在末尾找到新的项目。

为什么要这样做,有什么办法可以让 NewProgram() 直接在末尾添加新程序?

如果有人认为“他应该使用带有 DTO 的 ViewModel”而不是直接使用 EF 对象,那么我已经走这条路很长一段时间了(Entity Framework and MVC 3: The relationship could not be changed because one or more of the foreign-key properties is non-nullable),到目前为止还没有有人明确地向我展示了如何实现这一点,并且仍然能够在同一个视图中添加和删除项目。要么是维护集合的索引出现问题,要么是实体框架不让我保存......而代码变成了一场噩梦。

这样我至少有可以理解的代码,唯一的事情是我需要以“正常”顺序完成此添加,即在集合末尾添加...

有什么想法吗?

顺便说一句:

这可行,但似乎没有必要先将新程序添加到 Consultant 对象,在没有新程序的情况下创建 ViewModel,然后将其单独添加到 ViewModel...

    public ActionResult NewProgram(int id)
    {
        //TODO: ordering is rather strange, because the entitycollection adds at the beginning rather than the end...
        Consultant consultant = _repository.GetConsultant(id);
        var vm = GetViewModel(consultant);
        var program = new Program();
        consultant.Programs.Add(program); 
        _repository.Save();
        vm.Programs.Add(program);
        return PartialView("ProgramList", vm);
    }

【问题讨论】:

    标签: asp.net-mvc entity-framework entitycollection


    【解决方案1】:

    根据http://blogs.msdn.com/b/adonet/archive/2009/12/22/poco-proxies-part-1.aspx ,您的导航属性Programs 被覆盖以调用某种DoLazyLoad() 方法。由于不需要更改属性实例本身,DoLazyLoad() 实际上可能是异步的,这可能是您注意到的行为的原因。

    由于无论如何您正在评估该列表,您可以在添加新程序之前致电ToList()。它只需要你稍微改变一下这条线:

    consultant.Programs.ToList().Add(new Program());
    

    如果这不起作用,请尝试:

    consultant.Programs.ToList();
    consultant.Programs.Add(new Program());
    

    这实际上不适用于我的“异步”理论,但可能会对您有所帮助。

    【讨论】:

    • 好吧,后者确实奏效了,虽然这似乎是一件相当随意的事情......但谢谢,无论如何它要好一点。
    • @Anders Svensson:我有点希望它不会起作用。如果您在视图中指定程序的顺序(例如按 ID 升序对它们进行排序),则可以避免这种“hack”。
    猜你喜欢
    • 1970-01-01
    • 2012-10-28
    • 2023-04-10
    • 2012-10-02
    • 2010-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多