Добавление в EntityCollection добавляет в конец коллекции в Entity Framework? - PullRequest
2 голосов
/ 01 марта 2011

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

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

И если кто-то думает, что «он должен использовать ViewModel» с DTO вместо прямой работы с объектами EF, хорошоЯ довольно долго шел по этому пути ( Entity Framework и MVC 3: связь не может быть изменена, потому что одно или несколько свойств внешнего ключа не могут иметь значение NULL ), и поэтомуДо сих пор никто не показал мне явно, как этого добиться, и все же иметь возможность добавлять и удалять элементы в одном представлении.Или проблема с поддержанием индексов коллекций, или 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 Ответ

1 голос
/ 01 марта 2011

Согласно 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());

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

...