我有两个SQL Express数据库,第一个有很多数据,但是我们构建了一个新的应用程序,它将在具有类似表结构的数据库上运行(添加了一些列,删除了一些,合并了几张桌子等)。客户端是相同的,他们希望在新应用程序中使用旧数据。
所以我现在要做的就是从旧数据库中移动数据(逐个表),将实体(手动)从旧格式转换为新格式然后最终将新实体保存在我的新数据库。
我使用的是Entity Framework,服务器是ASP.NET Web Api。我创建了两个单独的DbContext,一个用于旧DB,另一个用于新DB。 我能够从旧数据库中获取数据,对其进行转换,但后来遇到了我的问题,我需要将Identity列保持不变,以便我可以维护旧数据库中存在的关系,但是当我尝试保存实体时,EF告诉我,当Identity_Insert为OFF时,我不能在Identity Column中插入值。
这是我的实际错误讯息:
无法为表格中的标识列插入显式值' AccessoryProfiles'当IDENTITY_INSERT设置为OFF时。
这是我尝试迁移数据的控制器方法:
public IHttpActionResult Get()
{
try
{
var manager = new MigrationManager<AccessoryProfile>();
var entities = manager.GetAll();
foreach (var profile in entities)
{
var newEntity = new Entities.Server.Accessories.AccessoryProfile
{
Id = profile.AccessoryProfileId,
Name = profile.Name,
CreatedDate = profile.CreatedDate,
LastModifiedDate = profile.LastModifiedDate,
DeletedDate = profile.DeletedDate
};
DataService.AccessoryProfile.Add(newEntity);
}
DataService.AccessoryProfile.Commit();
return Ok();
}
catch (Exception exc)
{
Logger.Error(exc);
return null;
}
}
MigrationManager<T>
处理旧数据库,而DataService
处理新数据库。
我尝试在Id上设置[DatabaseGenerated(DatabaseGeneratedOption.None)],但没有运气。我在Commit()之前试过运行它:
DbContext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT [dbo].[AccessoryProfiles] ON");
...但我仍然无法在标识栏中插入值。
我应该如何使用Entity Framework执行此操作? 或者如果你知道一种比使用EF更好的方法,那我就是全部的耳朵。 谢谢!
答案 0 :(得分:2)
如果要插入整个表,我建议使用EntityFramework.BulkInsert。对于很多记录,“。Add”或“.AddRange”扩展非常慢。
以下是bulkinsert的描述和速度优势: https://efbulkinsert.codeplex.com/
您还可以查看此主题以获取更多信息: Fastest Way of Inserting in Entity Framework
设置SqlBulkCopy时,它允许您使用不同的SqlBulkCopyOptions重载它。我相信其中一个是“KeepIdentity”,它允许你保持源身份。我想这可能就是你要找的东西。
因此,当您设置sqlbulkcopy对象时,您可能会编写如下内容:
SqlBulkCopy copy = new SqlBulkCopy(sqlConn, SqlBulkCopyOptions.KeepIdentity| SqlBulkCopyOptions.Default, null);
另外请确保不要使用“CheckConstraints”选项。