Я работаю над своим первым приложением ASP.NET MVC (бета-версия для версии 3) (использующим EF4) и немного борюсь с некоторыми соглашениями о сохранении новой записи и обновлении существующей.Я использую стандартное сопоставление маршрутов.
Когда пользователь переходит на страницу / сеанс / оценку, он может ввести новую запись и сохранить ее.У меня есть действие, определенное так:
[ActionName("Evaluate")]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EvaluateSave(EvaluteSessionViewModel evaluatedSession)
{
}
Когда они сохраняются, я беру сущность из модели представления, присоединяю ее к своему контексту и сохраняю.Все идет нормально.Теперь я хочу, чтобы пользователь мог редактировать эту запись через url / session / Evaluate / 1, где '1' - это идентификатор записи.
Редактировать: моя сущность EF присоединена как свойство к представлениюМодель.
Если я добавлю перегруженный метод, как этот (чтобы я мог получить часть '1' автоматически).
[ActionName("Evaluate")]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EvaluateSave(ID, EvaluteSessionViewModel evaluatedSession)
{
}
Я получаю сообщение об ошибке «Текущий запрос действия« Оценить »для типа контроллера« SessionsController »является неоднозначным между следующим действием».Я не уверен, почему они неоднозначны, так как они выглядят уникальными для меня.
Я решил, что сейчас собираюсь пропустить эту проблему и посмотреть, смогу ли я получить ее для обновления существующей записи, поэтому я закомментировал EvaluateSave, у которого не было параметра ID.
Я хотел бы сделать следующее:
// Load the original entity from EF
// Rebind the postback so that the values posted update the entity
// Save the result
Поскольку сущность заполняется как параметр (оценочный сеанс), повторное связывание происходит слишком рано.Но когда я посмотрел на подход, который хотел бы использовать, я понял, что он открывает мой код для взлома (поскольку пользователь может добавлять поля на опубликованную заднюю страницу, и они могут переопределять значения, которые я установил в сущности).
Так что мне кажется, что мне приходится вручную проверять каждое поле, чтобы увидеть, изменилось ли оно и, если оно есть, обновить его.Примерно так:
if (evaluatedSession.MyEntity.myField <> savedSession.myField)
savedSession.myField = evaluatedSession.MyEntity.myField;
Или сохраните копию сущности и убедитесь, что ни одна из не редактируемых пользователем не изменилась.Гадость.
Итак, два вопроса:
Первый: как избавиться от перегруженных методов?
Второе: есть ли лучший способ обработки обновления ранее сохраненной записи?
Редактировать: Я думаю, я мог бы использовать что-то вроде Automapper ...
Редактировать 9/22/ 2010 - ОК, похоже, это должно работать с комбинацией двух элементов: вы можете контролировать, какие поля связывать (и, в частности, исключать некоторые из них), с помощью атрибута [Bind (Exclude = "field1, field2")] либона уровне класса или как часть метода, выполняющего сохранение, напр.
public ActionResult EvaluateSave([Bind(Exclude="field1")] EvaluateSessionViewModel evaluatedSession)
С точки зрения EF вы должны иметь возможность использовать метод ApplyCurrentValues () из контекста, например.
context.ApplyCurrentValues(savedEval.EntityKey.EntitySetName, evaluatedSession);
Конечно, это не такПохоже, работать на меня.Я продолжаю получать «Объект с ключом, который совпадает с ключом предоставленного объекта, не может быть найден в ObjectStateManager. Убедитесь, что значения ключа предоставленного объекта соответствуют значениям ключа объекта, к которому должны быть применены изменения».
Я попытался присоединить исходную сущность, которую только что загрузил, на тот случай, если она по какой-то причине не была присоединена к контексту (до ApplyCurrentValues):
context.AttachTo(savedEval.EntityKey.EntitySetName, savedEval);
По-прежнему происходит сбой.Я предполагаю, что это как-то связано с типом объекта сущности EF, который создает MVC (возможно, он недостаточно заполнен, чтобы EF4 что-то с ним сделал?).Я надеялся включить .NET Framework, чтобы пройтись по нему, чтобы посмотреть, что он пытается сделать, но, похоже, EF4 не является частью сделки.Я посмотрел на него с помощью Reflector, но мне немного сложно представить, что происходит.