2

我正在尝试创建一个视图,用户可以在其中添加项目而无需转到新视图(该场景是一种 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() 直接在末尾添加新程序?

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

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

有任何想法吗?

顺便提一句:

这行得通,但似乎没有必要首先将新程序添加到 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);
    }
4

1 回答 1

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());

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

于 2011-02-28T22:28:07.313 回答