2016-08-26 22 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"); 
    } 

以下の関数を使用して主キー値を生成する際にエラーを取得する:

SR_NOはそのテーブルの主キーである
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; 
     } 
    } 

ご協力いただければ幸いです。前もって感謝します。

+0

並列ループ内のループデータベースに接続し、主キーの最大値のチェック:あなたのデータベースとしてSQL Serverを使用している場合は、関連するコードは次のようになります。 Parallelは非常に悪い考えです。少なくとも、IDを生成する部分をスレッドセーフにする必要があります。 – user3185569

+0

parallel.foreachを使用する必要がない場合は、ユーザー定義のコレクションを使用し、ユーザー定義のコレクションを使用して一括でレコードを挿入する方がよいでしょう。サンプルの例が見つかります。 – Meena

答えて

0

このような挿入を行う最も速い方法は、ADO.NET、特にSQL Bulk Insertを使用することです。

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); 
} 
関連する問題