调用ToList()

时间:2017-01-11 11:42:51

标签: c# entity-framework entity-framework-6 change-tracking

我很难理解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方法的代码中看到,我们有一个列表的用户,我们正在修改该列表。

现在我知道这是有效的,它是我一直这样做的方式但是我总是认为列表中的对象(在这种情况下是用户)是对DBSet Local集合中相应对象的引用。

经过一番思考后,我不确定是否就是这种情况,好像上下文已被处理,列表仍然被填充并且可以被操纵(我们只是没有能力将其推回到数据库而无需额外的工作)所以从这个角度来看,列表中的项目必须是来自DBSet Local集合的项目的副本......但是如果是这种情况我不会操作列表中的对象会对dbset中的对象,因为它将是一个副本。

摘要

问题是当我在DBSet上调用ToList时会发生什么?在这种情况下,更改跟踪如何工作? - 我知道它确实有效,但我认为我目前的理解可能不正确。

2 个答案:

答案 0 :(得分:1)

EF有一个集合,其中跟踪了所有待处理的更改(_context.ObjectStateManagersee here...)。使用EF的更多加载实体可以获得代理实例,而不是真正的实体类。使用此代理EF会将代码“注入”实体实例,以更新跟踪信息。

当您处置上下文时,您会丢失此信息。要将现有实体实例添加到另一个上下文,您可以使用_context.Attach()方法。

SaveChanges()会处理_context.ObjectStateManager信息。

答案 1 :(得分:0)

您需要使用context.TableName.Update(obejct)标记更新的对象。接下来使用context.Savechanges();保存更改,所以在您的示例中

public void ProcessUsers()
{
    _users = _dal.GetUsers();

    foreach(var u in users)
    {
        u.user.Comment = "This is a test";
        _dal.Users.Update(u);
    }

    _dal.SaveChanges();
}
相关问题