Словарь одного общего типа - PullRequest
0 голосов
/ 12 марта 2019

Я пишу программу, которая читает некоторые трехмерные виртуальные модели, а затем записывает некоторую информацию (различных типов, таких как 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 , конечно, также не является решением, так как оно по-прежнему содержит значение для объекта.

Что я могу сделать, чтобы избежать бокс в этой ситуации и, следовательно, добиться лучшей производительности?

Спасибо за любой совет!

...