Добавление в EntityCollection добавляет в конец коллекции в Entity Framework?

Я пытаюсь создать представление, в котором пользователь может добавлять элементы в коллекцию, не переходя в новое представление (сценарий представляет собой своего рода сайт с резюме, где пользователь добавляет информацию об опыте работы, навыках и т. Д., И это кажется абсурдным переходить в новый вид, чтобы добавить каждую мелочь).

Итак, у меня есть представление редактирования, которое показывает несколько текстовых полей для уже добавленных элементов, и есть вызов 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, он добавляет новую программу к объекту Консультанта и создает новую ViewModel для отправки обратно, но добавляет новую программу в начало EntityCollection, а не в конец. Но затем, когда вы публикуете всю форму и снова открываете окно редактирования, в конце списка будет добавлена ​​новая добавленная программа. Это очень странно Пользователь будет думать, что он / она добавляет элемент в начале списка, но если он снова вернется на страницу, он найдет новый элемент в конце.

Почему это происходит, и есть ли способ заставить NewProgram() добавить новую программу в конец напрямую?

И если кто-то думает, что "он должен использовать ViewModel" с DTO вместо того, чтобы работать непосредственно с объектами EF, ну, я уже довольно долго шел по этому пути ( Entity Framework и MVC 3: отношения не могли быть изменены потому что одно или несколько свойств внешнего ключа не обнуляются), и до сих пор никто явно не показал мне, как этого добиться, и все же иметь возможность добавлять и удалять элементы в одном представлении. Или проблема с поддержанием индексов коллекций, или Entity Framework не позволит мне сохранить... И код стал кошмаром.

Таким образом, по крайней мере, у меня есть понятный код, и единственное, что мне нужно, чтобы это добавление было выполнено в "обычном" порядке, то есть добавить в конце коллекции...

Есть идеи?

КСТАТИ:

Это работает, но кажется очень ненужным сначала добавить новую программу в объект "Консультант", создать 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);
    }

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

Это на самом деле не работает с моей "асинхронной" теорией, но может помочь вам.

Другие вопросы по тегам