Я пишу программу, которая читает некоторые трехмерные виртуальные модели, а затем записывает некоторую информацию (различных типов, таких как int, float, datetime и т. Д.) В базу данных SQL.
В БД есть много таблиц с разными структурами (разное количество столбцов разных типов), поэтому я хочу написать метод для вставки в БД достаточно общим образом, чтобы мне не нужно было писать конкретный метод для каждый стол.
Для этого я строю команду SQL с помощью StringBuilder, используя словарь, чтобы получить правильные параметры из метода, вызывающего метод вставки:
public static object WriteDbTable(string tableName, Dictionary<string, object> valuesToWrite)
{
try
{
using (SqlConnection connection =
new SqlConnection(ConnectToDB().ConnectionString))
{
// Open connection to db
connection.Open();
// Create SQL command object
SqlCommand command = connection.CreateCommand();
// Build string with list of columns where to input values in db
// To be plugged into command creation
StringBuilder columnsString = new StringBuilder();
for (int i = 0; i < valuesToWrite.Keys.Count; i++)
{
if (i < valuesToWrite.Keys.Count - 1)
{
columnsString.Append('[' + valuesToWrite.Keys.ElementAt(i) + "], ");
}
else
{
columnsString.Append('[' + valuesToWrite.Keys.ElementAt(i) + "]");
}
}
// Build string with list of values to input in db
// To be plugged into command creation
StringBuilder valuesString = new StringBuilder();
for (int i = 0; i < valuesToWrite.Keys.Count; i++)
{
if (i < valuesToWrite.Keys.Count - 1)
{
valuesString.Append('@' + valuesToWrite.Keys.ElementAt(i) + ", ");
}
else
{
valuesString.Append('@' + valuesToWrite.Keys.ElementAt(i));
}
}
// Build the SQL instruction
command.CommandText = string.Format(
"insert into {0} ({1}) values ({2});",
tableName,
columnsString,
valuesString
);
// build command values
foreach (KeyValuePair<string, object> pair in valuesToWrite)
{
command.Parameters.AddWithValue($"@{pair.Key}", pair.Value);
}
// Execute command getting back the identity (/primary key) of the insertion
return command.ExecuteNonQuery();
}
}
Таким образом, в основном методе я могу, например, вызвать это:
private void WriteTimestamp()
{
// What time is the audit starting?
DateTime timestamp = DateTime.Now;
// Write file information to the AUDITS table
Dictionary<string, object> stamp = new Dictionary<string, object>()
{
{ "auditDate", timestamp }
};
}
И время после того, как я могу вызвать это без написания определенного метода для него:
private void WriteGenericFileInfo(int auditId, string filePath)
{
// Write file information to the FILES table
Dictionary<string, object> fileInfo = new Dictionary<string, object>()
{
{ "auditId", auditId },
{ "projectId", 2 },
{ "disciplineId", 1 },
{ "filePath", filePath },
{ "fileSize", Utilities.BytesToMB(new FileInfo(filePath).Length) }
};
}
Теперь это прекрасно работает, поскольку мне просто нужно управлять одним методом для записи любого типа данных в базу данных в таблицы, которые имеют разное количество столбцов разных типов.
Проблема заключается в том, что мне нужно неявно box Значение словаря каждый раз, и в какой-то момент мне придется написать несколько тысяч записей за один прогон программы, поэтому я боюсь, что это сильно скажется на производительности (программы, а не базы данных).
Использование типа dynamic , конечно, также не является решением, так как оно по-прежнему содержит значение для объекта.
Что я могу сделать, чтобы избежать бокс в этой ситуации и, следовательно, добиться лучшей производительности?
Спасибо за любой совет!