I'm currently trying to bulkinsert a datatable into a database. It works fine and fast. The only problem occurs if there are any rows that are already in the database (duplicate key).
To counter this I have modified my program so that I first check for each new entry if it already exists in the database or not. Which is.......slow (In the current cases I don't have many entries but later on its over 200k entries that I need to check and that a few times). Thus I need to make it faster as it is now (if possible).
The datatable is structured this way:
DataTable transactionTable.Columns.Add("DeviceId", typeof(Int32));
transactionTable.Columns.Add("LogDate", typeof(DateTime));
transactionTable.Columns.Add("LogType", typeof(Int32));
transactionTable.Columns.Add("LogText", typeof(String));
transactionTable.PrimaryKey = new DataColumn[3] {
transactionTable.Columns[0],
transactionTable.Columns[1],
transactionTable.Columns[2]
};
What I have so far is the following:
DataTable insertTable = transactionTable.Copy();
insertTable.Clear();
using (SqlConnection sqlcon = new SqlConnection(this.GetConnString()))
{
sqlcon.Open();
foreach (var entry in transactionTable.AsEnumerable())
{
using (SqlCommand sqlCom = sqlCon.CreateCommand())
{
sqlCom.Parameters.Clear();
sqlCom.CommandText = "SELECT 1 FROM myTable WHERE"
+ " DeviceId = @DeviceId AND LogDate = @LogDate"
+ " AND LogType = @LogType"
sqlCom.Parameters.AddWithValue("@DeviceId", entry.Field<Int32>("DeviceId"));
sqlCom.Parameters.AddWithValue("@LogDate", entry.Field<DateTime>("LogDate"));
sqlCom.Parameters.AddWithValue("@LogType", entry.Field<Int32>("LogType"));
using (SqlDataREader myRead = sqlCon.ExecuteReader()
{
myRead.Read();
if (myRead.HasRows == false)
{
insertTable.Rows.Add(entry.ItemArray);
}
}
}
}
}
// And afterwards the bulkinsert which I think is out of scope for the question itself
// (I use the insertTable there)
Now my question is: Is there any way to do this faster in order to not get the key violation problem?