使用实体框架保存记录和保留主键的正确方法是什么

时间:2015-02-11 19:33:21

标签: sql-server entity-framework entity-framework-6 sql-insert

我正在尝试将数据播种到Entity Framework 6中新创建的数据库中。(或者即时替换它)这是用于开发/测试目的,可能用于将来的生产安装。我有几个从生产环境导出的XML文件,我需要进入开发和测试环境。要做到这一点,我需要将主键保留在查找表中。下面的代码显示了我最终如何工作。我花了一天的时间搜索“正确的方法”来完成它,遗憾的是最终硬编码了一个查询字符串,如代码所示。

public void Add(QuestionType questionType)
{
  using (var context = new SurveyFromDBContext())
  {
    using (var dbContextTransaction = context.Database.BeginTransaction())
    {
      try
      {
        context.Database.ExecuteSqlCommand(@"SET IDENTITY_INSERT [Kiosk].[QuestionTypes] ON");
        string sql = "INSERT INTO [KIOSK].[QuestionTypes] ( [Id], [Name], [Description]) VALUES (" +
          questionType.Id + ", '" + questionType.Name + "', '" + questionType.Description + "')";
        context.Database.ExecuteSqlCommand(sql);

        //context.QuestionTypes.Add(questionType);

        context.SaveChanges();
        context.Database.ExecuteSqlCommand(@"SET IDENTITY_INSERT [Kiosk].[QuestionTypes] OFF");
        dbContextTransaction.Commit();
      }
      catch (Exception e)
      {
        dbContextTransaction.Rollback();
      }
    }
  }
}

问题是:在EF6中,如何将记录插入表中并保留主键?

请注意,由于遗留代码,主键需要能够自动更新,因此我无法执行此操作:

[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Id { get; set; }

除非能以某种方式即时完成。

1 个答案:

答案 0 :(得分:0)

我不相信有任何好方法可以做到这一点。你正在做的事情让我更像是一个与ETL相关的任务而不是ORM任务。

对您所拥有的内容进行了一项改进(已测试;与您上面描述的DatabaseGeneratedOption结合使用)。我不相信需要关闭identity_insert;无论如何,它在恢复后恢复为关闭:

        using ( var context = new YourEntities() )
        {
            var connection = (SqlConnection)context.Database.Connection;
            using ( var cmd = new SqlCommand( "set identity_insert QuestionTypes on", connection) )
            {
                connection.Open();
                cmd.ExecuteNonQuery();
            }

            var qt = new QuestionType { id = 2, name = "test" };
            context.QuestionTypes.Add( qt);
            context.SaveChanges();
        }