Как обновить сущность в Entity Framework 4 .NET - PullRequest
10 голосов
/ 29 августа 2010

мой код выглядит примерно так:

public class Program
{
 [STAThread]
 static void main()
 {
  DataAccessClass dal = new DataAccessClass();
  List<Person> list = dal.GetPersons();
  Person p = list[0];
  p.LastName = "Changed!";
  dal.Update(p);
 }
}

public class DataAccessClass
{
 public static List<Person> GetPersons()
 {
  MyDBEntities context = new MyDBEntities();
  return context.Persons.ToList();
 }

 public void Update(Person p)
 {
  // what sould be written here?
 }
}

Теперь, пожалуйста, скажите мне, что я должен написать в методе Update ()?все, что я пишу, встречает различные исключения.(обратите внимание, что загруженные данные отслеживаются, подключены или что-то в этом роде)

Ответы [ 3 ]

20 голосов
/ 29 августа 2010

Проблема в том, что ваши сущности Person все еще привязаны к контексту, созданному в GetPersons.Если вы хотите работать с присоединенными сущностями, вы должны использовать один и тот же экземпляр контекста в операциях выбора и обновления.У вас есть два варианта решения вашей проблемы.

1) Правильно обработанные присоединенные сущности

public class Program 
{ 
  [STAThread] 
  static void main() 
  { 
    using (DataAccessClass dal = new DataAccessClass())
    {
      List<Person> list = dal.GetPersons(); 
      Person p = list[0]; 
      p.LastName = "Changed!"; 
      dal.Save();
    } 
  } 
} 

public class DataAccessClass : IDisposable
{ 
  private MyDBEntities _context = new MyDBEntities(); 

  public List<Person> GetPersons() 
  { 
    return _context.Persons.ToList(); 
  } 

  public void Save() 
  { 
    // Context tracks changes on your entities. You don't have to do anything. Simply call
    // SaveChanges and all changes in all loaded entities will be done in DB.
    _context.SaveChanges();
  } 

  public void Dispose()
  {
    if (_context != null)
    {
      _context.Dispose();
      _context = null;
    }
  }
}

2) Не используйте прикрепленные сущности

public class Program 
{ 
  [STAThread] 
  static void main() 
  { 
    DataAccessClass dal = new DataAccessClass())
    List<Person> list = DataAccessClass.GetPersons(); 
    Person p = list[0]; 
    p.LastName = "Changed!"; 
    dal.Update(p);
  } 
} 

public class DataAccessClass
{ 
  public static List<Person> GetPersons() 
  {
    // Closing context will detach entities
    using (MyDBEntities context = new MyDBEntities())
    { 
      return context.Persons.ToList(); 
    }
  } 

  public void Update(Person p) 
  {  
    using (MyDBEntities context = new MyDBEntities())
    {
      context.Persons.Attach(p);
      // Detached entities don't track changes so after attaching you have to say
      // what changes have been done
      context.ObjectStateManager.ChangeObjectState(p, System.Data.EntityState.Modified);
      context.SaveChanges();
    }
  } 
}
2 голосов
/ 19 марта 2011

Взято из Стартового комплекта информации о сотрудниках , вы можете рассмотреть фрагмент кода, как показано ниже:

public void UpdateEmployee(Employee updatedEmployee)
        {
            //attaching and making ready for parsistance
            if (updatedEmployee.EntityState == EntityState.Detached)
                _DatabaseContext.Employees.Attach(updatedEmployee);
            _DatabaseContext.ObjectStateManager.ChangeObjectState(updatedEmployee, System.Data.EntityState.Modified);
            _DatabaseContext.SaveChanges();
        }
0 голосов
/ 18 октября 2010

не работает, если у вас есть свойство объекта, являющегося ConcurrencyToken. По крайней мере для меня. Потому что вы получите исключение OptimisticConcurrencyException.

Что я делаю (и я думаю, что это не оптимальное решение),

факты: - Я использую новый контекст из-за n-уровня. Итак, предыдущий / оригинальный объект с его значениями неизвестен. Либо вы предоставляете контекст с оригинальным и старым (ба), либо как я, загружайте оригинал первым до обновления:

T originalItem = sessionManager.Set().Single(x => x.ID == changedEntity.ID);</p> <pre><code> if(changedEntity.lastChangedDate != originalItem.lastChangedDate) throw new OptimisticConcurrencyException(String.Format("Trying to update entity with lastChangedDate {0} using lastChangedDate {1}!", originalItem.lastChangedDate, changedEntity.lastChangedDate)); ObjectStateEntry state = sessionManager.ObjectStateManager.GetObjectStateEntry(originalItem); state.ApplyCurrentValues(changedEntity); state.ChangeState(System.Data.EntityState.Modified); sessionManager.SaveChanges();

Если вы знаете что-то лучше, пожалуйста, дайте мне знать.

Atam

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...