EF和数据导入

时间:2012-08-28 11:17:06

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

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

假设这是操作序列:

  1. 获取数据
  2. 将其转换为适合EF型号
  3. 将每个实体添加到DbContext
  4. 保存更改
  5. 问题在于它不会按原样插入标识值,因为我的主键设置为标识列。

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

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

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

    问题:如果我更改模型,我还需要更改导入查询,因此我需要在两个地方维护数据库结构。

    有关EF如何实现这一目标的任何建议?我没有丝毫想法为什么EF团队在调用ExecuteSqlCommand之后决定总是关闭连接。

2 个答案:

答案 0 :(得分:2)

为了配合EF DbContext,以下是需要做的事情:

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

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

有关性能的有趣读物可以在这里找到:

Fastest Way of Inserting in Entity Framework

答案 1 :(得分:1)

我认为正确的方法是放弃Identity值在源和目标DB中保持相同的要求。如果将数据导入EF模型以保持关系完好无损,即创建父对象然后正确添加其子项,那么您的结构和关系将保持不变。

无论如何,你永远不会在查询中使用身份值,所以对于他们的价值观没有任何意义。

如果不出意外,这将更加可维护。

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

<DatabaseGenerated(DatabaseGeneratedOption.None)>

装饰来实现这一点。