2012-02-13 2 views
1

Я создал очень простое приложение MVC3, чтобы сделать небольшую демонстрацию, но я столкнулся с проблемой; Я возвращаю объект в свое представление, редактирую его, а затем отправляю обратно, но в этом процессе моя сущность теряет возможности отслеживания изменений. Когда я возвращаю объект к моему представлению, он все еще является прокси-классом сущностной структуры, но когда он возвращается из моего представления, это класс «Человек» (объект называется человеком).Сущности теряют отслеживание изменений при редактировании с помощью MVC3

Вот мой репозиторий класс:

public class PersonRepository : IPersonRepository 
{ 
    public EfContext Uow { get; set; } 

    public PersonRepository(IUnitOfWork uow) 
    { 
     Uow = uow as EfContext; 
    } 

    // yada yada yada 

    public void Add(Person person) 
    { 
     Uow.Persons.Add(person); 
    } 
} 

Этот объект отправляется на мой взгляд, что имеет простую форму, созданную с Html.EditorForModel. После этого я верну его обратно этому методу:

[HttpPost] 
public ActionResult Edit(Person person) 
{ 
    if (ModelState.IsValid) 
    { 
     _personRepository.Add(person); 
     _personRepository.Uow.Commit(); 

     return RedirectToAction("Index"); 
    } 

    return View(person); 
} 

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

public class EfContext : DbContext, IUnitOfWork 
{ 
    public DbSet<Account> Accounts { get; set; } 
    public DbSet<Person> Persons { get; set; } 

    public void Commit() 
    { 
     SaveChanges(); 
    } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); 
    } 
} 

Кстати, это моя сущность класс:

public class Person 
{ 
    [HiddenInput(DisplayValue = false)] 
    public Guid Id { get; set; } 

    public string FirstName { get; set; } 

    public string LastName { get; set; } 

    public virtual ICollection<Account> Accounts { get; set; } 
} 

Кто-нибудь знает, как чтобы исправить это? Я работал над этим до того, насколько помню, я просто не знаю, как это сделать.

Заранее благодарен!

ответ

1

Определите метод Update в вашем репозитории, который будет прикреплять объект и помечать его как измененный.

public class PersonRepository : IPersonRepository 
{ 
    // yada yada yada 

    public void Add(Person person) 
    { 
     Uow.Persons.Add(person); 
    } 

    public void Update(Person person) 
    { 
     Uow.Persons.Attach(person); 
     Uow.Entry(person).State = EntityState.Modified; 
    } 
} 

[HttpPost] 
public ActionResult Edit(Person person) 
{ 
    if (ModelState.IsValid) 
    { 
     _personRepository.Update(person); 
     _personRepository.Uow.Commit(); 

     return RedirectToAction("Index"); 
    } 

    return View(person); 
} 
+0

Звучит так, как будто это сработает. Но разве это не так «плохо»? Это звучит немного грязно, чтобы явно установить состояние. –

+1

@ Avalaxy No. Это часть процесса, когда вы присоединяете объект, потому что EF не знает состояния объекта. Репозиторий должен знать о деталях реализации. – Eranga

2

Я предполагаю, что вы создаете ваше хранилище для каждого запроса (в конструкторе или передается в виде зависимости по вашей рамки IoC или что-то). В этом случае объект, который вы получаете в своем методе контроллера, действительно не отслеживается, потому что он был создан в другом запросе. Вы должны «прикрепить» его к контексту и пометить его как измененный, чтобы EF знал, что он изменился, и его необходимо сохранить в БД

+0

Да, репозиторий вводится в мой контроллер контейнером DI. Спасибо за ваш ответ, возможно, это решение. –

0

Здесь есть 3-е решение, которое, по моему мнению, является самым отказоустойчивым.

Вы можете настроить действие MVC для получения целого числа id. Затем, используя это целое число, вы извлекаете объект из базы данных. Затем вы вызываете метод UpdateModel на контроллере. Это свяжет новые значения формы с вашим существующим объектом, в то время как оно не изменяет неизменные свойства и свойства, которые, возможно, не были в форме.

Смежные вопросы