开发者

Adding to EntityCollection adds to the end of collection in Entity Framework?

I'm trying to have a View where the user can add items in a collection without having to go to a new View (the scenario is a sort of CV site where the user adds info about work experience, skills, etc, and it would seem absurd to go to a new View to add each little thing).

So I have an edit View that shows a number of text boxes for the already added items, and there's an ajax call to go to a method to fetch the collection fresh if the user adds an item.

Here are the methods in question:

    public ActionResult Edit(int id)
开发者_JAVA百科    {
        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);
    }

Now to the question: When the NewProgram method is called, it adds a new program to the Consultant object and creates a new ViewModel to send back, but it adds the new program to the start of the EntityCollection, not at the end. But then when you post the entire form, and you open the Edit View again, the list will have placed the new added program at the end. This is very strange. The user will think he/she adds an item at the start of the list, but if they go back to the page again, they will find the new item at the end.

Why does it do this, and is there any way I can make NewProgram() have the new program added at the end directly?

And if anyone is thinking "he should be using a ViewModel" with DTOs instead of working directly with EF objects, well, I've been down that road for quite a while now ( Entity Framework and MVC 3: The relationship could not be changed because one or more of the foreign-key properties is non-nullable ), and so far no one has shown me explicitly how to achieve this and still be able to both add and remove items in the same View. There is either a problem with maintaining the indexes of the collections or the Entity Framework won't let me save... And the code became a nightmare.

This way I at least have understandable code, and the only thing is I need to have this adding done in the "normal" order, i.e. add at the end of the collection...

Any ideas?

BTW:

This works, but it seems very unnecessary to first have to add the new program to the Consultant object, create the ViewModel without the new program, and then add it to the ViewModel separately...

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


According to http://blogs.msdn.com/b/adonet/archive/2009/12/22/poco-proxies-part-1.aspx , your navigation property Programs is overridden to invoke some kind of DoLazyLoad() method. Since the property instance itself isn't necessarly changed, DoLazyLoad() might actually by asynchronous, which could account for the behavior you're noticing.

Since you are evaluating the list anyhow, you could call ToList() before adding the new program. It would require you to only change the line a bit:

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

If this doesn't work, try:

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

This actually doesn't work well with my "asynchronous" theory, but might help you out.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜