【问题标题】:MySql data to Microsoft Sql by using Entity Framework使用实体框架将 MySql 数据传输到 Microsoft Sql
【发布时间】:2017-12-24 06:01:00
【问题描述】:

我的项目使用实体框架时遇到问题。我已经成功建立了这两个数据库之间的连接。我正在考虑实际从数据库中复制 mysql 数据并插入到 microsoft sql 中。我对这个实体框架很陌生,这里有人可以指导我如何做到这一点吗?任何帮助将不胜感激。

【问题讨论】:

  • 似乎您正在寻找的是这两个 DBMS 之间的批量复制。包括您尝试将批量记录从源数据库插入到其他数据库的任何代码。

标签: c# mysql sql-server entity-framework


【解决方案1】:

问题在于 Id 的生成。最简单和最安全的方法是让新的 DbContext 生成 Id,就好像元素被添加为新对象一样

这意味着您必须从旧数据库中读取所有元素并将它们添加到新数据库中。

using (var oldDbContext = ...)
{
    using (var newDbContext = ...)
    {
         var oldItems = oldDbContext.OldTable.ToList();
         foreach (var oldItem in oldItems)
         {
             var newItem = converOldItem(newItem);
             // you need your Id to have default value (zero)!
             var addedNewItem = newDbcontext.NewTable.Add(newItem);
         }
         ...
         newDbContext.SaveChanges();
     }
}

如果您有一对多的关系,您将需要 addedNewItem。例如,如果老师有很多学生,那么您的老师在SaveChanges 之前不会有TeacherId。因此,您不能将教师的 ID 分配给学生中的外键。您必须:

var newStudentToAdd = ConvertFromOld(oldStudent);
newSturdentToAdd.Teacher = addedTeacher;

这一切的缺点是内存中会有很多数据,转换过程会相当慢。优点:非常安全,并且在转换过程中您可以进行(默认)更改。

您可以通过禁用对目标数据库中更改的检测来提高速度,从而强制保存所有内容,而不检查数据是否更改。

因为你正在创建一个新的数据库,所有数据都被添加了,因此所有数据都应该被保存,因此你不需要更改检测:DbContextConfiguration.AutoDetectChangesEnabled Property

newDbContext.Configuration.AutoDetectChangesEnabled = false;

另一个更危险的方法是重用现有的 ID。如果您这样做,您必须自己为转换过程之后将添加的所有项目生成 id。确保以后生成ID与旧数据库中生成ID的方法兼容。

如果您决定自己生成 ID。覆盖`DbContext.SaveChanges1:

class NewDbContext : DbContext
{
    ...
    public override int SaveChanges()
    {
        GenerateIds();
        base.SaveChanges();            
    }

    private void GenerateIds()
    {
        foreach (var addedEntry in this.ChangeTracker.Entries
            .Where(entry => entry.State == EntityState.Added))
        {
            ((IID)addedEntity).Id = idGenerator.CreateId();
        }
    }
}

为此,每个Entry(DbSet 中带有主键的每个类)都应该有一个指示主键的接口,如下所示:

public interface IID
{
    int Id {get; set;}
}

public class Teacher : IID
{
     public int Id {get; set;}
     ...
}
public class Student : IID
{
     public int Id {get; set;}
     ...
} 

IdGenerator 应该创建与旧数据库的 IdGenerator 相似的 ID。在转换过程中,您想使用旧数据库的 Id,因此请确保不会重新创建这些 Id

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-08-06
    • 2017-07-07
    • 2011-09-09
    • 2010-10-14
    • 1970-01-01
    • 1970-01-01
    • 2015-02-15
    • 1970-01-01
    相关资源
    最近更新 更多