【问题标题】:EF and data importEF和数据导入
【发布时间】:2012-08-22 21:27:00
【问题描述】:

我正在开发我首先使用 EF 代码 (v4.4) 作为 ORM 和 SqlServer 作为数据库的应用程序。我还需要一个选项来从另一个具有相似数据结构的数据库类型中导入数据。在数据传输期间,我需要使用它们所具有的值传输标识列,以免破坏相关数据。

假设这是操作顺序:

  1. 获取数据
  2. 将其转换为适合 EF 模型
  3. 将每个实体添加到 DbContext
  4. 保存更改

问题是它不会插入原来的标识值,因为我的主键设置为标识列。

解决这个问题的方法之一是使用 IDENTITY_INSERT 命令,但它需要在同一个连接周期下与插入查询一起执行。连接周期是指在所有操作(IDENTITY_INSERT 和 INSERT INTO)期间不得关闭连接。

问题:ExecuteSqlCommand 会关闭连接,即使它在调用之前已显式打开。

解决此问题的方法是不使用 EF 执行此任务,而是使用 ADO.NET SqlCommand。这样我们就可以更好地控制何时打开/关闭连接。

问题:如果我改变我的模型,我也需要改变导入查询,所以我需要在两个地方维护数据库结构。

任何建议如何使用 EF 实现这一目标?我不知道为什么 EF 团队决定在调用 ExecuteSqlCommand 后总是关闭连接。

【问题讨论】:

    标签: entity-framework entity-framework-4 ef-code-first


    【解决方案1】:

    为了使用 EF DbContext,需要做的是:

    • 使用 IObjectContextAdapter 打开连接
    • 使用 ObjectContext 的 ExecuteStoreCommand 打开/关闭 IDENTITY_INSERT
    • 在 DbContext 中有一个构造函数,在该构造函数中,您可以在进行数据转换时关闭 DatabaseGeneratedOption.Identity for PKs

    至于性能,我发现最好的方法是对 X 记录进行批量更新,然后处置/重新创建上下文。另外,将 AutoDetectChangesEnabled 设置为 false

    可以在此处找到有关性能的有趣阅读:

    Fastest Way of Inserting in Entity Framework

    【讨论】:

      【解决方案2】:

      我认为正确的做法是放弃对标识值在源数据库和目标数据库中保持相同的要求。如果您将数据导入 EF 模型并保持关系不变,即创建一个父对象,然后正确添加其子对象,那么您的结构和关系将保持不变。

      无论如何,您永远不会在查询中使用标识值,因此不必担心它们的值。

      如果不出意外,这将更易于维护。

      另一个选项是将 PK 列创建为常规可插入列,而不是自动生成。在 POCO 中,使用

      <DatabaseGenerated(DatabaseGeneratedOption.None)>
      

      装饰来实现这一点。

      【讨论】:

      • 您好 GilShalit,我已经花时间考虑您的方法,但我认为这不是最好的方法。如果您认为我错了,请告诉我在哪里。在将要转换的数据库中,有一些拥有超过 100 万条记录。如果我将 AutoDetectChangesEnabled 设置为 True,则需要花费大量时间才能完成这项工作。目前,在我处理/重新创建 DbContext 之后,我正在为不超过 100 个实体进行更新。这种方法提供了巨大的性能提升。将所有记录保存在内存中,同时保持关系,会大大减慢速度。
      • 您不需要将所有内容都保存在内存中。创建 LINQ 对象并在每 10,000 次添加或任何此类数字中使用一次 SaveChanges 没有问题。
      • 我认为在数据库之间保留 Identity 值通常是无用的工作。
      • 我同意,但它只能应用于“少量”记录(比如说
      • 查看(真正的)大数据案例的第二个选项。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-30
      • 2011-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多