使用Entity Framework,LINQ和MVC在数据库之间复制数据

时间:2013-05-16 07:35:18

标签: sql asp.net-mvc performance linq entity-framework

有一个问题。我有一些带有一些数据的旧数据库,另一方面我有新结构的新数据库。

现在我需要最好的方法(想法)如何将数据从一个表复制到另一个表。问题是一些表有最多1000条记录,大约32000条,大约64万条,复制5000条的时间真的很长。

任何最佳做法?以下示例代码......

public ActionResult ImportTable1()
{
   var oldTable1 = context.OLDTABLE.ToList();

   foreach (var item in oldTable1)
   {
      try
      {
          var cTable = contextNew.NEWTABLE.Where(p => p.fiel1 == item.field1).FirstOrDefault();

          if (cTable == null)
          {
             NEWTABLE nTable = new NEWTABLE
             {
                                field1 = item.field1,
                                field2 = item.field2
             };

             contextNew.NEWTABLE.Add(nTable);
          }
          else
          {
             cTable.field1 = item.field1
             cTable.field2 = item.field2;

             contextNew.Entry(cTable).State = EntityState.Modified;
          }

          IcontextNew.SaveChanges();
      }
      catch (DbEntityValidationException dbEx)
      {
         foreach (var validationErrors in dbEx.EntityValidationErrors)
         {
            foreach (var validationError in validationErrors.ValidationErrors)
            {
               _progresLog = ("Property: " + validationError.PropertyName + " Error: {1}" + validationError.ErrorMessage);
            }
         }
     }

   return PartialView();
}

...现在批量

    public void ExperimentalPartsBulk()
    {
        string msisDatabase = ConfigurationManager.ConnectionStrings["old"].ToString();
        string newDatabase = ConfigurationManager.ConnectionStrings["new"].ToString();

        SqlConnection sourceconnection = new SqlConnection(msisDatabase);
        SqlConnection sourcedestination = new SqlConnection(newDatabase);


        sourceconnection.Open();
        SqlCommand cmd = new SqlCommand("Select * from ELEMENTS");
        cmd.Connection = sourceconnection;
        SqlDataReader reader = cmd.ExecuteReader();

        //Connect to Destination DataBase
        SqlConnection destinationConnection = new SqlConnection(newDatabase);
        destinationConnection.Open();


        SqlBulkCopy bulkCopy = new SqlBulkCopy(destinationConnection);
        bulkCopy.DestinationTableName = "ELEMENTSNEW";
        bulkCopy.ColumnMappings.Clear();
        bulkCopy.ColumnMappings.Add("fielString1", "newString1");
        bulkCopy.ColumnMappings.Add("fielString2", "newStrin2");
        bulkCopy.ColumnMappings.Add("fielFloat1", "newINT1");
        bulkCopy.WriteToServer(reader);
        reader.Close();

        sourceconnection.Close();
        sourcedestination.Close();

    }

问题现在是两个表之间的差异

fielString1 可以为null, newString1 不能为| fielFloat1 浮动现在可以为空但 newINT1 不是

如何导入某些条件或不同类型的字段?

2 个答案:

答案 0 :(得分:0)

希维克,

第一个代码示例中显示的任何循环都会因性能问题而失败....正如您所指出的那样!

这里的正确方法是SQL方法。我们的想法是将所有数据“刷新”到新数据库。 Flush意味着ALL记录(5,000或500,000)通过一个操作存储到新DB中!并且在提取,过滤,编辑和保存数据期间避免任何循环,因为640,000循环需要很长时间....

批量复制是可能的。批量复制问题是您很难过滤和编辑此对象中的数据。

使用ADO.net DataSet从旧数据库中获取数据,对其进行过滤,编辑并将其保存在内存中,然后将其刷新到新数据库。 DataSet每个操作一步(提取,过滤,编辑等!没有循环)。

或者,尝试SQL复制。复制是将数据从DB“A”表“oneTable”复制到另一个DB的“SQL”机制,“B”具有带有不同模式和规则的表“AnotherTable”。试试吧。如果您认为这是一个合理的解决方案,我可以指定更多。无需代码,可以使用SQL Management Studio上的向导创建,并在需要时运行(通过SQL作业代理)。

答案 1 :(得分:0)

您应该认真考虑SSIS或bcp。否则,您正在查看一个场景,即您将数据从源服务器一直拉到执行.net代码的客户端盒,然后将所有数据推送到目标服务器。想想消耗的带宽。如果您可以将SSIS导出到目的地,至少可以消除额外的关注层。

如果绝对必须将数据下载到客户端,请考虑将数据写入bcp格式的文件,然后将它们批量复制到目标服务器中。

我很确定您会发现这两种路径都比使用普通的旧ADO.NET方法快得多。