【问题标题】:Entity Framework CTP 5 - Repository pattern - doing updates实体框架 CTP 5 - 存储库模式 - 进行更新
【发布时间】:2011-01-28 01:27:11
【问题描述】:

您将如何使用 CTP 5 使用 DbContext 和使用存储库模式进行更新操作?早期使用 EF 4.0,可以像下面这样完成。

_context.Customers.AddObject(item);
_context.ObjectStateManager.ChangeObjectState(item, System.Data.EntityState.Modified);

EF 不提供更新“断开连接”实体的简单方法是否有任何原因。我不想查询数据库并将所有属性复制到从查询返回的对象中。换句话说,EF 应该有接收实体的 update 方法(类似于 Add 方法)。如果实体键已存在于数据库中,则使用当前值更新实体。即我们为什么要“附加”然后将所有属性复制到附加对象。对我来说,复制实体的所有属性只是为了在“断开连接”对象已经存在时进行更新似乎是多余的。

【问题讨论】:

    标签: entity-framework entity


    【解决方案1】:

    我相信您仍然可以执行与代码示例中相同的方法来使用 CTP5 DbContext 更新断开连接的实体:

    _dbContext.Customers.Add(item);
    DbEntityEntry entry = _dbContext.Entry(item);
    entry.State = EntityState.Modified;
    
    _dbContext.SaveChanges();
    

    查看生成的 SQL,这当然会在客户对象的所有属性上创建一个完整的更新语句,包括实际未更改的属性,因为 EF 不知道数据库中的当前状态是什么。如果你想避免这种情况,我想除了在更新之前获取数据库中的当前状态之外别无他法:

    DbEntityEntry entry = _dbContext.Entry(_dbContext.Customers.Find(item.ID));
    entry.CurrentValues.SetValues(entity);
    
    _dbContext.SaveChanges();
    

    (假设您的客户对象“项目”上有一个键 ID。)

    这将创建一个 SQL 更新语句,其中仅包含与数据库中的状态相比确实发生了变化的属性。由于附加的 select 语句,我不确定第二种方式是否必然是性能较低的选项。如果对象类型很大,但只有很少的属性发生了变化,则在所有字段上发送完整更新语句的开销可能大于选择语句加上仅包含更新真正需要的字段的“小”更新语句。 (但这只是猜测,我不是 SQL Server 专家。)

    【讨论】:

    • 这正是我想要的。谢谢。我在这方面还有另一个问题,在stackoverflow.com/questions/4167033/… 的评论中提出。让我知道你的想法。 “您将如何使用 EF CTP 5 中的 DbContext 和“Ado.net DbContext 生成器”来执行此操作?没有修复代码,因此设置 DirectorId 不会清除 Director。在将 DirectorId 设置为我唯一的选项后始终设置 movie.Director = null ?”
    • 对不起,我真的不知道,我到现在都没用过 DbContext 生成器。
    • 顺便说一句:如果您在这里没有得到关于 CTP5 的满意答案,EF 预发布论坛可能是另一个好去处:social.msdn.microsoft.com/Forums/en-US/adonetefx/threads
    • 找到我要找的东西。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多