Частичное обновление объекта с помощью EF Code First и ASP.NET MVC - PullRequest
4 голосов
/ 03 мая 2011

EF4.1-Code-First-Gurus!

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

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

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

В моем хранилище есть следующий метод обновления. Метод исключает список полей, которые следует обновить (оставив поля CreatedOn / 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;
    }

Теперь контроллер вызывает этот метод так:

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

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

Может быть, это похожий вопрос: Как обновить объект EF 4 в ASP.NET MVC 3?

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

1 Ответ

7 голосов
/ 03 мая 2011

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

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

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

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