Entity Framework C# - 将数据从一个数据库移动到另一个具有相似结构的数据库

Posted

技术标签:

【中文标题】Entity Framework C# - 将数据从一个数据库移动到另一个具有相似结构的数据库【英文标题】:Entity Framework C# - Moving data from one database to another with similar structure 【发布时间】:2016-08-22 16:46:05 【问题描述】:

我有两个 SQL Express 数据库,第一个数据库中有很多数据,但我们构建了一个新应用程序,它将在具有相似表结构的数据库上运行(添加一些列,删除一些列,合并一些列表等)。客户端也是一样,他们想在新应用程序中使用旧数据。

所以我现在要做的是从旧数据库中移动数据(逐个表),将实体(手动)从旧格式转换为新格式,然后最后将新实体保存在我的新数据库中.

我使用的是实体框架,服务器是 ASP.NET Web Api。我创建了两个单独的 DbContext,一个用于旧数据库,一个用于新数据库。 我能够从旧数据库中获取我的数据,对其进行转换,但是后来我遇到了我的问题,我需要身份列保持不变,以便我可以维护旧数据库中存在的关系,但是当我尝试保存实体,EF 告诉我,当 Identity_Insert 为 OFF 时,我无法在身份列中插入值。

这是我的实际错误消息:

当 IDENTITY_INSERT 设置为 OFF 时,无法为表“AccessoryProfiles”中的标识列插入显式值。

这是我尝试迁移数据的控制器方法:

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&lt;T&gt; 处理旧数据库,而DataService 处理新数据库。 我尝试在 Id 上设置 [DatabaseGenerated(DatabaseGeneratedOption.None)] ,但没有运气。我在 Commit() 之前尝试过运行它:

DbContext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT [dbo].[AccessoryProfiles] ON");

...但我仍然无法在身份列中插入值。

我应该如何使用实体框架来做到这一点? 或者,如果您知道比使用 EF 更好的方法,我会全神贯注。 谢谢!

【问题讨论】:

您可以将 SQL Server 中的数据导出到 .csv,将其转换为 .xls,然后将其导入新数据库。更改 .xls 文件中的架构应该不是问题。 你不能在 SQL 查询中这样做吗?这种传输数据的方法可能会让人非常头疼。您可能会面临许多其他问题(例如这个问题),这些问题在 SQL 中都更容易处理。我建议您编写查询,例如 insert into from select ...等。还要记住要担心主键和外键之间的引用完整性。祝你好运。 请检查您是否正在运行 DbContext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT [dbo].[AccessoryProfiles] ON");针对接收数据库上下文,而不是发送数据库上下文? 您是否有理由在代码中执行此操作,而不是使用 RedGate、XSQL、DevArt 等工具?这些工具中内置了用于在数据传输期间处理身份列的方法。这是一个必须重复的过程吗? 我在代码中这样做的原因是它是唯一让我感到舒服的环境,并且我可以循环遍历表格并动态地进行更改。我在 SQL 查询方面很糟糕,想避免它们,但是将数据库导出到 .xls 并在那里进行更改听起来是一个不错的选择,除了我在特定表中有大约 12k 项并进行这些更改必须动态制作。我看一下 excel 功能,因为我也不精通。 【参考方案1】:

如果要插入整个表,我建议使用 EntityFramework.BulkInsert。对于很多记录,“.Add”或“.AddRange”扩展非常慢。

这里是 bulkinsert 的描述和速度优势: https://efbulkinsert.codeplex.com/

您还可以查看此线程以获取更多信息: Fastest Way of Inserting in Entity Framework

在设置 SqlBulkCopy 时,它允许您使用不同的 SqlBulkCopyOptions 对其进行重载。我相信其中之一是“KeepIdentity”,它允许您保留源身份。我想这可能就是你要找的。​​p>

因此,当您设置 sqlbulkcopy 对象时,您可能会编写如下内容:

SqlBulkCopy copy = new SqlBulkCopy(sqlConn, SqlBulkCopyOptions.KeepIdentity| SqlBulkCopyOptions.Default, null);

同时确保您没有使用“CheckConstraints”选项。

【讨论】:

谢谢。我正在尝试完成这项工作,我找到了 KeepIdentity 设置,但没有收到密钥插入错误。但是我得到“支持“DbContext”的模型已经改变......”我尝试了新的迁移,但没有待处理的更改。我已删除数据库并首先使用代码重新创建它,但我收到此错误。我仍然运行与上述相同的方法。不同之处在于我在 DataService 中运行 'DbContext.BulkInsert(entities, new BulkInsertOptions SqlBulkCopyOptions = SqlBulkCopyOptions.KeepIdentity );' 而不是 'DbContext.Add(entity);'。有什么想法吗? 顺便说一句,错误指向我的新数据库的 DbContext,而不是我的旧数据库。 发生错误是因为当我安装 BulkInsert 时,它出于某种原因将我的实体框架降级为 6.0.0。我更新了EF,错误消失了!您的解决方案运行顺利,我将整个表格格式化并准备好在我的新数据库中使用正确的身份列。非常感谢!

以上是关于Entity Framework C# - 将数据从一个数据库移动到另一个具有相似结构的数据库的主要内容,如果未能解决你的问题,请参考以下文章

C# WPF Entity Framework 6 同步数据库

使用 Entity Framework Core 将数据存储和检索为 JSON 字符串?

在 C# 中使用 Entity Framework Core 插入数据之前检查重复字符串数据的最佳实践

Entity Framework C# Insert Data 俄语编码问题

使用 Entity Framework 5 将大量数据从旧数据库移动到新数据库

如何使用 Oracle 和 SQL Server 将 .NET 4.5 C# Entity Framework 6 中的列映射为大写?