Jestem obecnie robi coś takiego:
DataTable objects = new DataTable();
DataColumn keyColumn = new DataColumn("name", typeof(string));
DataColumn versionColumn = new DataColumn("version", typeof(int));
versionColumn.DefaultValue = iVersionID;
objects.Columns.Add(keyColumn);
objects.Columns.Add(versionColumn);
foreach (KeyValuePair<string, NamedObject> kvp in Directory)
{
NamedObject o = kvp.Value;
DataRow row = objects.NewRow();
row[0] = o.Name;
objects.Rows.Add(row);
}
using (SqlBulkCopy updater = new SqlBulkCopy(conn,
SqlBulkCopyOptions.TableLock | SqlBulkCopyOptions.UseInternalTransaction, null))
{
updater.DestinationTableName = "object_table";
updater.WriteToServer(objects);
}
string sQuery = @"SELECT id, name FROM object_table WHERE version = @ver";
using (SqlCommand command = new SqlCommand(sQuery, conn))
{
SqlParameter version = new SqlParameter("@ver", SqlDbType.Int, 4);
version.Value = versionID;
command.Parameters.Add(version);
command.CommandTimeout = 600;
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
string key = (string)reader[1];
NamedObject item = Directory[key];
item.ID = (int)reader[0];
}
}
}
pamiętać, że nasz projekt danych umożliwia filtrowanie dla wszystkich naszych nowych obiektów za pomocą identyfikatora wersji; każdy dodawany wiersz będzie miał ten sam identyfikator wersji, a my wcześniej usunęliśmy wszystkie wiersze w bazie danych, które już posiadały ten identyfikator wersji.
Jednak moje zapytanie wybierające ma obecnie limit czasu w ExecuteReader, nawet w tym 10-minutowym oknie. To nie jest nasze ostateczne rozwiązanie.
W rzeczywistości zatrzymaliśmy to rozwiązanie, rozwiązując problemy z przekroczeniem limitu czasu, konfigurując proces wygasania starych i nieistotnych danych. Dodałem kolumnę znacznika czasu i kolumnę "keep" do tabeli wersji i dodałem tryb, który usuwa wszystkie dane powiązane z wersjami starszymi niż miesiąc bez flagi "keep". Nasze problemy z przekroczeniem limitu czasu zniknęły po usunięciu ~ 100 milionów wierszy. – Timbo