如何在Entity Framework 4 .NET中更新实体

时间:2010-08-29 11:22:10

标签: entity-framework ado.net

我的代码是这样的:

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 个答案:

答案 0 :(得分:20)

问题是您的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();
    }
  } 
}

答案 1 :(得分:2)

Employee Info Starter Kit获取,您可以将代码段视为如下:

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

答案 2 :(得分:0)

当您在EnturrencyToken的实体上拥有属性时,

不起作用。 至少对于我来说。因为然后你得到一个OptimisticConcurrencyException。

我做什么(我认为这不是最佳解决方案),

事实: - 因为n层,我使用新的上下文。因此,具有其值的先前/原始实体是未知的。要么提供原始和旧(bah)的上下文,要么像我一样在更新前加载原始文件:

T originalItem = sessionManager.Set().Single(x => x.ID == changedEntity.ID);

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

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