【问题标题】:Committing changes to the database using Entity Framework使用实体框架提交对数据库的更改
【发布时间】:2011-10-18 17:34:34
【问题描述】:

我有一种情况,我按日期从表中提取数据。如果没有为给定日期提供数据,我将使用默认值创建一条记录并将其全部显示给用户。当用户完成对数据的操作后,我需要提交更改。

所以我的问题是如何在 Entity Framework 中处理提交一个表,在该表中可能需要完成更新和添加。这是在 C# 中使用 MVC3 和实体框架。

这就是数据开始时的样子,

表 A

NAME  AGE PHONE_NUM 
Jim   25  555-555-5555 
Jill  48  555-551-5555

用户处理完数据后,它可能看起来像这样,

表 A

NAME  AGE PHONE_NUM
Jim   25  555-555-5555
Jill  28  555-551-5555
Rob   42  555-534-6677

如何提交这些更改?我的问题是需要更新和插入吗?

我找到了一些这样的代码,但我不知道它是否适用于这种情况。

用于添加数据行

entities.TABlEA.AddObject(TableOBJECT);
entities.SaveChanges();

或用于更新数据

entities.TABLEA.Attach(entities.TABLEA.Single(t => t.NAME == TableOBJECT.NAME));
entities.TABLEA.ApplyCurrentValues(TableOBJECT);
entities.SaveChanges();

这些是否可行,或者我是否需要跟踪那里的内容和添加的内容?

想法?

【问题讨论】:

    标签: c# asp.net-mvc-3 entity-framework


    【解决方案1】:

    您或多或少已经有了解决方案。您只需要检查尝试从数据库加载对象的Single 调用是否有结果(改用SingleOrDefault)。如果结果是null则需要插入,否则更新:

    foreach (var TableOBJECT in collectionOfYourTableOBJECTsTheUserWorkedWith)
    {
        var objectInDB = entities.TABLEA
            .SingleOrDefault(t => t.NAME == TableOBJECT.NAME);
        if (objectInDB != null) // UPDATE
            entities.TABLEA.ApplyCurrentValues(TableOBJECT);
        else // INSERT
            entities.TABLEA.AddObject(TableOBJECT);
    }
    entities.SaveChanges();
    

    (我假设 NAME 是您的 TableOBJECT 实体的主键属性。)

    【讨论】:

    • 那么SingleSingleOrDefault有什么区别?
    • 单次检查查询是否只有一个结果。如果没有结果 Single 将抛出异常。 SingleOrDefault 检查一个结果,如果查询为空,它将返回默认值(大多数情况下为 NULL)。因此,当应该始终有一个结果时,请使用 Single。当可能根本没有结果时使用 SingleOrDefault。
    • 所以我花了一些时间才找到可以使用它的地方,它很棒,除非它必须添加更多的东西,我从数据库中得到一个异常,抱怨没有唯一的键。想法?
    • @Slauma: 这是 entities.SaveChanges(); 上的例外情况@ "InvalidOperationException 对数据库的更改已成功提交,但在更新对象上下文时发生错误。ObjectContext 可能处于不一致的状态。内部异常消息:AcceptChanges 无法继续,因为对象的键值与 ObjectStateManager 中的另一个对象冲突。在调用 AcceptChanges 之前,请确保键值是唯一的。”
    • 我调查了这是第一次机会异常,据我所知,这意味着它可能会在以后导致异常,但现在不会。所以我抓住它,忽略它,一切都正常工作。这听起来安全吗?还是我真的应该想办法阻止它?
    【解决方案2】:

    我认为您必须跟踪什么是新的,什么是修改的。如果你这样做,那么你提供的两个代码示例将起作用。 我使用的一个简单解决方法是检查实体的主键属性是否设置为任何值。如果它被设置为一个值,那么这是一个更新的对象,否则它是新的。

    另一种解决方案是使用实体框架的自我跟踪实体,但我认为这不是在 Web 应用程序中的正确方向(可能是在分布式 WCF 应用程序中)。

    【讨论】:

      猜你喜欢
      • 2014-04-13
      • 2014-06-16
      • 2016-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多