Частично обновляемый объект с EF Code First и ASP.NET MVC

EF4.1-Code-First-Gurus!

Интересно, есть ли более элегантный способ обработать следующий сценарий ASP.NET MVC 3 EF 4.1 Code First: Допустим, у нас есть следующие POCOs:

public class Entity
{
 [Key]
 public int Id { get; set; }
 [ScaffoldColumn(false)]
 public DateTime CreatedOn { get; set; }
 [ScaffoldColumn(false)]
 public DateTime ModifiedOn { get; set; }
}

и

public class Person : Entity
{
 public string FirstName { get; set; }
 public string LastName { get; set; }
 public DateTime Birthday { get; set; }
}

Предположим, мы создали некоторые стандартные виды редактирования, которые не включают в себя поля CreateOn/ModifiedOn, поскольку они будут установлены в репозитории, а не пользователем.

В моем репозитории у меня есть следующий метод обновления. Методы исключают список полей, которые необходимо обновить (оставляя выделенные поля CreateOn/ModifiedOn):

public void Update(Person person, List<string> properties)
 {
 Person tmpPerson = context.People.Single(x => x.Id == person.Id);
 context.People.Attach(tmpPerson);
 foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(person))
 {
 if (properties.Contains(descriptor.Name))
 descriptor.SetValue(tmpPerson, descriptor.GetValue(person));
 }
 tmpPerson.ModifiedOn = DateTime.Now;
 }
</string>

Теперь контроллер вызывает этот метод следующим образом:

[HttpPost]
 public ActionResult Edit(Person person)
 {
 if (ModelState.IsValid) {
 personRepository.Update(person, new List<string> { "FirstName", "LastName", "Birthday"});
 personRepository.Save();
 return RedirectToAction("Index");
 } else {
 return View();
 }
 }
</string>

Все это работает как шарм. Однако мне очень не нравится, что я должен указать поля вручную. Как бы вы справились с этим требованием? Конечно, я мог бы добавлять поля CreateOn/ModifiedOn в качестве скрытых полей в представление, но я не хочу, чтобы выгружать форму на много (Есть гораздо больше полей).

Возможно, это аналогичный вопрос: Как обновить объект EF 4 в ASP.NET MVC 3?

Я высоко ценю вашу помощь! Джорис

1 ответ

Да, есть более элегантная версия:

public void Update(Person person, params Expression<func<person,object>>[] properties)
{
 context.People.Attach(person);
 DbEntityEntry<person> entry = context.Entry(person);
 foreach (var property in properties)
 {
 entry.Property(property).IsModified = true;
 }
 person.ModifiedOn = DateTime.Now;
}
</person></func<person,object>

Вы вызовете метод следующим образом:

[HttpPost]
public ActionResult Edit(Person person)
{
 if (ModelState.IsValid) 
 {
 personRepository.Update(person, p => p.FirstName, 
 p => p.LastName, p => p.Birthday);
 personRepository.Save();
 return RedirectToAction("Index");
 } 
 else 
 {
 return View(person);
 }
}

licensed under cc by-sa 3.0 with attribution.