【问题标题】:Entity framework change tracking after calling ToList()调用 ToList() 后的实体框架更改跟踪
【发布时间】:2017-01-11 11:42:51
【问题描述】:

我很难理解 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 时会发生什么,以及在这种情况下更改跟踪如何工作? - 我知道它确实有效,但我认为我目前的理解可能不正确。

【问题讨论】:

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


    【解决方案1】:

    EF 有一个集合,其中跟踪所有挂起的更改(_context.ObjectStateManagersee here...)。进一步使用 EF 加载实体,您将获得一个代理实例,而不是您的真实实体类。使用此代理 EF 会将代码“注入”到您的实体实例中,从而更新更改跟踪信息。

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

    SaveChanges() 确实处理了_context.ObjectStateManager 信息。

    【讨论】:

    • 嗨,对不起,我的问题并不清楚,我知道更改跟踪是如何工作的,并且上面示例中的代码可以工作。我想我要问的是,当我在 DBset 上调用 toList 时,该列表中的内容... dbSet 中项目的副本或对这些对象的引用?经过一番挖掘并与工作中的其他人交谈后,我相当确定列表必须填充对 dbSet 内容的引用而不是副本。
    【解决方案2】:

    您需要使用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();
    }
    

    【讨论】:

    • 嗯,不,这就是我的意思,我发布的代码没有损坏,它可以正常工作。我只是想了解 DBSet 上的 ToList() 的作用,我现在假设列表中填充了对 dbset Local 集合中原始对象的引用。但是从我读到的不是,它们是副本-但是,如果是这种情况,则更改跟踪将不起作用并且上述代码将失败。
    猜你喜欢
    • 2011-04-23
    • 1970-01-01
    • 2014-12-08
    • 2011-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-26
    • 2011-09-09
    相关资源
    最近更新 更多