Как добавить параметры и выполнить универсальный IDbCommand

Вот моя проблема в деталях. Я создал класс слоя доступа к данным, который позволяет мне создавать большинство объектов, необходимых для взаимодействия с базами данных (Odbc, OleDb и SqlClient). Я также создал класс слоя обработки бизнес-объектов с интенсивным использованием Reflection для обработки множества задач с моими бизнес-объектами. Среди прочего, этот класс генерирует каждое отдельное свойство / объект, который мне нужен для обработки DAL (поток SQL, список значений, свойства, набор извлекаемых значений и т. Д.). Посмотрите код ниже для дальнейшего объяснения:

    Public Shared Function InvokeParam(Of T)(_classObject As T, _commandType As AdapterCommandType, _arguments As Object()) As Boolean
        Dim s As String = DAL.SCRFL.GetParamStatement(_classObject, _commandType, _arguments)
        'Debug.Print(s)
        Dim hT As Hashtable = DAL.SCRFL.GetProperties(_classObject)
        Using cnn As IDbConnection = DataFactory.CreateConnection()
            Dim cmd As IDbCommand = DataFactory.CreateCommand(s, cnn)
            'cmd.CommandType = CommandType.Text
            cmd.CommandText = s
            For Each k In hT
                Dim param As IDbDataParameter = cmd.CreateParameter()
                'param.DbType = DataFactory.ConvertToDbType(k.value.GetType)

                param.Value = k.value
                param.ParameterName = k.key
                'param.Direction = ParameterDirection.Input

                'Debug.Print("value:={0}, name:={1}", TypeName(k.value), TypeName(k.key))
                Debug.Print("typeMatch:={0}, value:={1}, name:={2}", TypeName(param.Value) = TypeName(k.value), param.Value, param.ParameterName)

                cmd.Parameters.Add(param)
            Next
            If (cmd.ExecuteNonQuery > 0) Then
                Return True
            End If
        End Using
        Return False
    End Function

Так, DAL.SCRFL.GetParamStatement возвращает строку в формате INSERT INTO t1 (f1, f2, f3...) values (?, ?, ?...) для вставки и соответствующих строк для обновления, удаления, выбора операторов. Все сделано с отражением. Здесь нет синтаксической ошибки. Я могу вручную выполнить возвращаемые значения с помощью прямых команд типа провайдера. DAL.SCRFL.GetProperties Метод возвращает хеш-таблицу, отформатированную как ключ = свойство (поле), значение = значение поля.

Теперь мне нужно создать параметры для каждого свойства и добавить его в параметры моей команды, а затем выполнить его. Эту попытку вы увидите в моем коде (я создаю параметры для каждой пары свойства / значения, зацикливая хеш-таблицу). Однако в конце я получаю исключение с Data type mismatch in criteria expression. описание. Я пытался добавить type свойство параметра объекта, size и т.д. все было неудачно (я их прокомментировал). Я пытался изменить param.Value = k.value в param.Value = If(IsDBNull(k.value), DBNull.Value, k.value) думая, что это может быть проблемой, хотя k.value это из моего бизнес-класса, и я намеренно предотвращаю нулевые значения. Ничего не получалось! вот тест; бизнес-класс вернул значение из DAL.SCRFL.GetParamStatement call: тест сделан для базы данных OleDb/Access, и, как вы можете видеть, я заключил поле Memo в одинарные кавычки. Мои методы отражения читают атрибуты свойств класса (которые я устанавливаю как имена полей таблицы) и DAL.SCRFL.GetParamStatement создает базовые операторы SQL для вставки, обновления, удаления и выбора использования. AdapterCommandType это встроенный тип enum для него).

INSERT INTO Clinics 
(ClinicId, ClinicName, Phone, Fax, FederalId, DateContracted, Address, City, State, Zip, Inactive, [Memo], DateEntered, EnteredBy, DateModified, ModifiedBy) 
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) 

Обратите внимание, что у меня есть другой метод, похожий на этот, который выполняет оператор SQL (InvokeSql), где я тщательно проверяю типы значений для каждого свойства, чтобы создать пары свойство = значение в моем операторе SQL. Используя полностью квалифицированную инструкцию SQL в этом, InvokeSql, метод работает без одного предупреждения (Rouphly: cnn As IDbConnection = CreateConnection(), cmd = CreateCommand(_cmdText, cnn), cmd.ExecuteNonQuery() где _cmdText это заявление SQL Нет параметров, как вы можете видеть!). Я упоминаю об этом, чтобы указать, что проблема возникает всякий раз, когда я использую параметры с общими IDbCommands. Несмотря на то, что внутри моей DataFactory IDbCommand установлен для конкретного типа команды поставщика (мой DataFactory.CreateCommand(s, cnn) возвращает универсальный IDbCommand).

До разработки DAL я выполнял все вышеперечисленные шаги вручную, хотя все объекты (команды, соединения и т. Д.) Были явно объявлены как типы, специфичные для провайдера. Говоря технически, я использую те же сценарии, что и при работе с объектами общего типа (не зависящими от поставщика). Но я не могу заставить это работать, где-то, возможно, я что-то упускаю.

1 ответ

Я разместил этот вопрос на codeproject, и ответ там. http://www.codeproject.com/Questions/446516/How-to-add-parameters-and-execute-a-generic-IDbCom

Другие вопросы по тегам