2016-08-26 26 views
0

在數據庫中插入多條記錄我試圖在數據庫中使用foreach循環插入大約5000條記錄。這需要大約10分鐘,這是不能接受的要求。我還考慮過首先在數據表中插入記錄,然後將其轉換爲XML的方法,將它傳遞給執行插入操作的存儲過程。但不幸的是,它不適合我的情況。現在我正在使用parallel.foreach做同樣的事情,但插入10條記錄後,我得到「主鍵唯一約束違規」錯誤消息。由於我是並行編程的新手,所以沒有得到解決方案。下面是我的代碼,我已經這麼做了。使用parallel.foreach

public ActionResult ChannelBulkUpload(HttpPostedFileBase excelFile) 
    { 
     bool flag = true; 

     string path = Server.MapPath("~/Content/UploadFolder/" + excelFile.FileName); 
     if (System.IO.File.Exists(path)) 
     { 
      System.IO.File.Delete(path); 
     } 
     excelFile.SaveAs(path); 

     DataTable dt = GetDataTableFromExcel(excelFile, true); 



     ParallelOptions options = new ParallelOptions 
     { 
      MaxDegreeOfParallelism = 4 
     }; 

     Parallel.ForEach(dt.AsEnumerable(), row => 
     { 

      flag = true; 
      decimal Key = 0; 
      string value = ""; 
      decimal channelMstKey = 0; 
      decimal channelGrpMstKey = 0; 
      decimal srcFuncKey = 0; 

      string ExcelMasterChDisplayName = row["MASTER_CHANNEL_DISPLAY_NAME"].ToString(); 
      string ExcelGenreValue = row["GENRE"].ToString(); 
      string ExcelAdsharpValue = row["ADSHARP"].ToString(); 
      string ExcelClusterValue = row["CLUSTER"].ToString(); 
      string ExcelNetworkValue = row["NETWORK"].ToString(); 
      string ExcelBroadCastValue = row["BROADCAST"].ToString(); 
      string ExcelFunctionalAreaname = row["FUNCTIONAL_AREA"].ToString(); 

      string[] Ch_Grp_types = { "GENRE", "ADSHARP", "CLUSTER", "NETWORK", "PLATFORM" }; 

      BarcDataContext bc = new BarcDataContext(); 
      srcFuncKey = bc.REF_SRC_FUNC_AREA.Where(m => m.SRC_FUNC_AREA == ExcelFunctionalAreaname).FirstOrDefault().SRC_FUNC_KEY; 

      for (int j = 0; j < Ch_Grp_types.Length && flag; j++) 
      { 

       if (Ch_Grp_types[j] == "GENRE") 
       { 
        Key = 1; 
        value = ExcelGenreValue; 
       } 
       else if (Ch_Grp_types[j] == "NETWORK") 
       { 
        Key = 2; 
        value = ExcelNetworkValue; 
       } 
       else if (Ch_Grp_types[j] == "ADSHARP") 
       { 
        Key = 3; 
        value = ExcelAdsharpValue; 
       } 
       else if (Ch_Grp_types[j] == "CLUSTER") 
       { 
        Key = 4; 
        value = ExcelClusterValue; 
       } 
       else if (Ch_Grp_types[j] == "PLATFORM") 
       { 
        Key = 5; 
        value = ExcelBroadCastValue; 
       } 

       DIM_CHANNEL_MST objChMst = bc.DIM_CHANNEL_MST.Where(m => m.CHANNEL_MST_NAME_UPPER == ExcelMasterChDisplayName.ToUpper().Trim()).FirstOrDefault(); 
       if (objChMst == null) 
       { 
        flag = false; 
       } 
       else 
       { 
        if (!string.IsNullOrEmpty(value)) 
        { 
         var query = 
            (from A in bc.XREF_CH_GRP_DET_TAG 
             join B in bc.XREF_CH_GRP_MST_TAG on A.CH_GRP_MST_KEY equals B.CH_GRP_MST_KEY 
             where A.IS_ACTIVE == "Y" && B.IS_ACTIVE == "Y" && B.CH_GRP_TYPE_KEY == Key && B.CH_GRP_MST_NAME_UPPER == value.ToUpper() 
             select new XrefChannelGrpDetailTagVM 
            { 
             channelGrpDetKey = A.CH_GRP_DET_KEY, 
             channelGrpMasterNameUpper = B.CH_GRP_MST_NAME_UPPER, 

            }).Distinct().ToList(); 

         var query2 = 
            (from A in bc.XREF_CH_GRP_DET_TAG 
             join B in bc.XREF_CH_GRP_MST_TAG on A.CH_GRP_MST_KEY equals B.CH_GRP_MST_KEY 
             where A.CHANNEL_MST_KEY == objChMst.CHANNEL_MST_KEY && B.CH_GRP_TYPE_KEY == Key && B.SRC_FUNC_KEY == srcFuncKey 
             select new XrefChannelGrpDetailTagVM 
             { 
              sr_no = A.SR_NO, 
              channelMstKey = A.CHANNEL_MST_KEY, 
              channelGrpDetKey = A.CH_GRP_DET_KEY, 
              channelGrpMstKey = A.CH_GRP_MST_KEY, 
              srcFuncKey = B.SRC_FUNC_KEY, 
              channelGrpTypeKey = B.CH_GRP_TYPE_KEY 

             }).Distinct().ToList(); 

         XREF_CH_GRP_MST_TAG objXrefChGrpMst = bc.XREF_CH_GRP_MST_TAG.Where(m => m.CH_GRP_TYPE_KEY == Key && m.SRC_FUNC_KEY == srcFuncKey && m.CH_GRP_MST_NAME_UPPER == value.ToUpper()).FirstOrDefault(); 

         if (objXrefChGrpMst != null) 
         { 
          channelMstKey = objChMst.CHANNEL_MST_KEY; 
          channelGrpMstKey = objXrefChGrpMst.CH_GRP_MST_KEY; 
          XREF_CH_GRP_DET_TAG objGrpDetail = new XREF_CH_GRP_DET_TAG(); 

          if (query.Count == 0) 
          { 
           objGrpDetail.CH_GRP_DET_KEY = Get_Max_Of_Ch_Grp_Det_Key(); 
          } 
          else 
          { 
           foreach (var detKey in query) 
           { 
            if (detKey.channelGrpMasterNameUpper == value.ToUpper()) 
            { 
             objGrpDetail.CH_GRP_DET_KEY = detKey.channelGrpDetKey; 
            } 
            else 
            { 
             objGrpDetail.CH_GRP_DET_KEY = Get_Max_Of_Ch_Grp_Det_Key(); 
            } 
           } 
          } 

          if (query2.Count > 0) 
          { 

           foreach (var abc in query2) 
           { 
            if (abc.channelMstKey == objChMst.CHANNEL_MST_KEY && abc.srcFuncKey == srcFuncKey && abc.channelGrpTypeKey == Key) 
            { 
             if (abc.channelGrpDetKey == objGrpDetail.CH_GRP_DET_KEY && abc.channelGrpMstKey == objXrefChGrpMst.CH_GRP_MST_KEY) 
             { 
              //Reject 
             } 
             else 
             { 
              //Update 
              XREF_CH_GRP_DET_TAG obj = bc.XREF_CH_GRP_DET_TAG.Where(m => m.SR_NO == abc.sr_no).FirstOrDefault(); 
              obj.CH_GRP_DET_KEY = objGrpDetail.CH_GRP_DET_KEY; 
              obj.CH_GRP_MST_KEY = objXrefChGrpMst.CH_GRP_MST_KEY; 
              objGrpDetail.CREATE_DATE = DateTime.Now; 
              objGrpDetail.LAST_UPD_DATE = DateTime.Now; 
              objGrpDetail.IS_ACTIVE = "Y"; 
              bc.SaveChanges(); 
             } 
            } 
            else 
            { 
             //Insert 
             objGrpDetail.CH_GRP_MST_KEY = channelGrpMstKey; 
             objGrpDetail.CHANNEL_MST_KEY = channelMstKey; 
             objGrpDetail.SR_NO = Get_Max_Of_XREF_CH_GRP_DET(); 
             objGrpDetail.CREATE_DATE = DateTime.Now; 
             objGrpDetail.LAST_UPD_DATE = DateTime.Now; 
             objGrpDetail.IS_ACTIVE = "Y"; 
             bc.XREF_CH_GRP_DET_TAG.Add(objGrpDetail); 
             bc.SaveChanges(); 
            } 

           } 
          } 
          else 
          { 
           objGrpDetail.CH_GRP_MST_KEY = channelGrpMstKey; 
           objGrpDetail.CHANNEL_MST_KEY = channelMstKey; 
           objGrpDetail.SR_NO = Get_Max_Of_XREF_CH_GRP_DET(); 
           objGrpDetail.CH_GRP_DET_KEY = objGrpDetail.CH_GRP_DET_KEY; 
           objGrpDetail.CREATE_DATE = DateTime.Now; 
           objGrpDetail.LAST_UPD_DATE = DateTime.Now; 
           objGrpDetail.IS_ACTIVE = "Y"; 
           bc.XREF_CH_GRP_DET_TAG.Add(objGrpDetail); 
           bc.SaveChanges(); 
          } 
         } 
        } 
       } 
      } 

     }); 
     TempData["SuccessMsg"] = "Records uploaded Successfully"; 

     return RedirectToAction("CreateChannel"); 
    } 

獲取錯誤使用下面的函數產生的主鍵值時:

public static decimal Get_Max_Of_XREF_CH_GRP_DET() 
    { 
     try 
     { 
      BarcDataContext bc = new BarcDataContext(); 
      return bc.XREF_CH_GRP_DET_TAG.Max(m => m.SR_NO) + 1; 

     } 
     catch (Exception e) 
     { 
      return 1; 
     } 
    } 

凡SR_NO是在該表中的主鍵。

任何幫助將非常感激。提前致謝。

+0

連接到數據庫並檢查主鍵的最大值的並行循環中的循環。這是一大麻煩,Parallel在這裏是一個非常糟糕的主意,或者至少你需要使生成ID的部分成爲線程安全的。 – user3185569

+0

如果不是強制使用parallel.foreach,那麼最好採用用戶定義的集合並使用用戶定義的集合在批量中插入記錄。你會找到示例。 – Meena

回答

0

執行此類插入操作的最快方法是使用ADO.NET,特別是SQL Bulk Insert。如果您將SQL Server用作數據庫,則相關代碼將如下所示:

DataTable dt = GetDataTableFromExcel(excelFile, true); 
using (var copy = new SqlBulkCopy(yourConnectionString) //There are other overloads too 
{ 
    BulkCopyTimeout = 10000, 
    DestinationTableName = dt.TableName, 
}) 
{ 
    foreach (DataColumn column in dt.Columns) 
    { 
     copy.ColumnMappings.Add(column.ColumnName, column.ColumnName); 
    } 
    copy.WriteToServer(dt); 
}