我很难理解EF6中的变更跟踪 .
我有类似的代码 .
public class SomeClass
{
private List<User> _users;
private DAL _dal;
public void ProcessUsers()
{
_users = _dal.GetUsers();
foreach(var u in users)
{
u.user.Comment = "This is a test";
}
_dal.SaveChanges();
}
}
DAL类看起来有点像这样 .
public class DAL
{
...
private DataContext _context; // Assume that this is being newed up in a constructor.
public List GetUsers()
{
return _context.Users.ToList();
}
public void SaveChanges()
{
_context.SaveChanges();
}
}
因此,正如我们从ProcessUsers方法中的代码中看到的那样,我们有一个 list 的用户,我们正在修改该列表 .
现在我知道这是有效的,它是我一直这样做的方式,但是我总是认为列表中的对象(在这种情况下是用户)是对DBSet Local集合中相应对象的引用 .
经过一番思考后,我不确定是否就是这种情况,就好像处理了上下文一样,列表仍然被填充并且可以被操作(我们只是没有能力将它推回到数据库而没有一些额外的工作)所以从那里透视列表中的项目必须是DBSet Local集合中的项目的副本...但是如果是这种情况我不会操作列表中的对象会对dbset中的对象产生任何影响这将是一个副本 .
In Summary
问题是当我在DBSet上调用ToList时会发生什么,以及在此实例中更改跟踪如何工作? - 我知道它确实有用,但我认为我目前的理解可能不正确 .
2 回答
EF有一个集合,其中跟踪所有挂起的更改(
_context.ObjectStateManager
,see here...) . 使用EF的更多加载实体可以获得代理实例,而不是真正的实体类 . 使用此代理EF将"injecting"代码添加到您的实体实例中,以更新跟踪信息 .处理上下文时,您将丢失此信息 . 要将现有实体实例添加到另一个上下文,可以使用
_context.Attach()
方法 .SaveChanges()
会处理_context.ObjectStateManager
信息 .您需要使用
context.TableName.Update(obejct)
标记更新的对象 . 接下来使用context.Savechanges();
保存更改 . 所以在您的示例中