我正在尝试将数据播种到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; }
除非能以某种方式即时完成。
答案 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();
}