Почему код нарушения работы ExpandoObject, который в остальном работает нормально?

Вот настройка: у меня есть проект с открытым исходным кодом под названием Massive , и я использую динамику как способ создания SQL на лету, и динамический результат устанавливает на лету.

Для работы с базой данных я использую System.Data.Common и ProviderFactory. Вот пример, который отлично работает (он статический, поэтому вы можете запускать его в консоли):

    static DbCommand CreateCommand(string sql) {
        return DbProviderFactories.GetFactory("System.Data.SqlClient")
                                  .CreateCommand();
    }
    static DbConnection OpenConnection() {
        return DbProviderFactories.GetFactory("System.Data.SqlClient")
                                  .CreateConnection();
    }
    public static dynamic DynamicWeirdness() {
        using (var conn = OpenConnection()) {
            var cmd = CreateCommand("SELECT * FROM Products");
            cmd.Connection = conn;
        }
        Console.WriteLine("It worked!");
        Console.Read();
        return null;
    }

Результатом выполнения этого кода будет «Это сработало!»

Теперь, если я изменю строковый аргумент на динамический - в частности, ExpandoObject (представьте, что где-то есть подпрограмма, которая преобразует Expando в SQL) - возникает странная ошибка. Вот код:

Dynamic Error

То, что работало раньше, теперь не работает с бессмысленным сообщением. SqlConnection - это DbConnection - более того, если вы наведете курсор мыши на код во время отладки, вы увидите, что все типы являются типами SQL. «conn» - это SqlConnection, «cmd» - это SqlCommand.

Эта ошибка совершенно бессмысленна - но, что более важно, она вызвана наличием ExpandoObject, который не затрагивает какой-либо код реализации. Различия между этими двумя подпрограммами следующие: 1 - я изменил аргумент в CreateCommand (), чтобы принять "динамический" вместо строки 2 - я создал ExpandoObject и установил свойство .

Становится еще более странным.

Если просто использовать строку вместо ExpandoObject - все работает отлично!

    //THIS WORKS
    static DbCommand CreateCommand(dynamic item) {
        return DbProviderFactories.GetFactory("System.Data.SqlClient").CreateCommand();
    }
    static DbConnection OpenConnection() {
        return DbProviderFactories.GetFactory("System.Data.SqlClient").CreateConnection();
    }
    public static dynamic DynamicWeirdness() {
        dynamic ex = new ExpandoObject();
        ex.TableName = "Products";
        using (var conn = OpenConnection()) {
            //use a string instead of the Expando
            var cmd = CreateCommand("HI THERE");
            cmd.Connection = conn;
        }
        Console.WriteLine("It worked!");
        Console.Read();
        return null;
    }

Если я заменяю аргумент CreateCommand () своим ExpandoObject («ex») - это приводит к тому, что весь код становится «динамическим выражением», которое оценивается во время выполнения.

Похоже, что оценка времени выполнения этого кода отличается от оценки времени компиляции ... что не имеет смысла.

** РЕДАКТИРОВАТЬ: я должен добавить здесь, что если я жестко запрограммирую все , чтобы явно использовать SqlConnection и SqlCommand, это сработает :) - вот изображение того, что я имею в виду:

enter image description here

38
задан Vadim Kotov 2 October 2019 в 10:34
поделиться