2016-12-07 42 views
5

在搜索通过EF执行CRUD操作的最佳实践时,我注意到强烈建议在更新实体之前使用Attach()Find()方法。它运行良好,根据EF文档,这些方法将实体提取到上下文中,这对我来说很清楚。但后续代码很困惑我为什么使用Attach for update实体框架6?

public void Update(object entity) 
{ 
    Record record = new Record() { 
     id = 1, 
     value = 5 
    }; 
    using (SomeContext ctx = new SomeContext()) 
    { 
     ctx.Entry(record).State = EntityState.Modified; 
     ctx.SaveChanges(); 
    } 
} 

假设我们在数据库中有id = 1的记录。在这种情况下,上面的代码将更新记录(将值设置为5)。问题是为什么它有效?那么为什么我应该使用Attach()?据我所知,该记录没有以任何方式附在上下文中。我阅读了this书和the tutorial的相关章节,但他们使用2-query-approach。我也冲浪,但没有找到我的问题的答案。请帮助我解释或一些好的matherials。

回答

12

如果您有一个您知道已经存在于数据库中的实体,但当前没有被上下文跟踪 - 您的情况 - 那么您可以使用方法在DbSet上告诉上下文以跟踪实体。因此总之,Attach方法会跟踪上下文中的实体并将其状态更改为Unchanged。当您修改某些属性后,跟踪更改将为您更改其状态为Modified。 在上面展示的情况下,您明确告知状态为Modified但这也会将实体附加到您的上下文。您可以在此post中找到详细的解释。

什么时候应该使用Attach方法?

当你有,你知道已经存在于数据库中,但要做出一些改变的实体:

var entity= new Entity{id=1}; 
context.YourDbSet.Attach(entity); 

// Do some change... 
entity.value=5; 

context.SaveChanges(); 

这是相同的:

context.Entry(entity).State = EntityState.Unchanged; 

// Do some change... 
entity.value=5; 

context.SaveChanges(); 

你应该在改变实体状态显式修改?

当你有一个你知道的实体已经存在于数据库中,但是已经做了改变。您的示例中的相同场景

+0

谢谢,但为什么此记录目前由上下文跟踪? –

+0

如果实体当前被跟踪并且您更改了某个属性,则由于跟踪更改,该实体的状态应该更改为'Modified',但是您的实体应该符合此要求(https://msdn.microsoft.com/ en-us/library/dd468057(v = vs.100).aspx) – octavioccl

+0

我认为这[link](https://www.safaribooksonline.com/library/view/programming-entity-framework/9781449331825/ch04s03.html )可以回答你的所有问题 – octavioccl