Dapper - нулевые значения вставляются в таблицу MySql - PullRequest
0 голосов
/ 04 октября 2019

После нескольких часов попыток выяснить проблему, я все еще застрял. Вот проблема:

У меня есть запрос MySql в моем коде C #:

var sql = "INSERT INTO MEMBERS(Salutation, FirstName, LastName) VALUES(?salutation, ?firstName, ?lastName)";

Этот запрос находится в методе, который принимает ExpandoObject:

public async Task AddMember(ExpandoObject expando)
{
    var sql = "INSERT INTO MEMBERS(Salutation, FirstName, LastName) VALUES(?salutation, ?firstName, ?lastName)";

    // Convert the incoming ExpandoObject to Dapper's DynamicParameters
    // /7621957/kak-dinamicheski-sozdavat-argumenty-dlya-dapper-zaprosa
    if (expando != null)
    {
        var dbArgs = new DynamicParameters();

        foreach (var param in expando)
        {
            dbArgs.Add(param.Key, param.Value);
        }

        await mySqlConnection.ExecuteAsync(sql, dbArgs);
    }
}

Запрос выполняется (это означает, что я не получаю сообщение об ошибке, и в таблице Members создается строка, а также генерируется значение столбца MemberId), но Salutation, FirstName и LastName равны нулю.

Я проверил содержимое Expando. Все входные значения есть.

Я пробовал разные вещи.

  • Использование @ и: вместо? в запросе.
  • Использование Expando напрямую в QueryAsync вместо преобразования его в DynamicParameters.
  • Использование IDictionary в качестве ввода вместо ExpandoObject и передача его непосредственно в QueryAsync.
  • Использование QueryAsync вместо ExecuteAsync.

Ничего не работает. 3 столбца равны нулю каждый раз. Не уверен, что здесь не так.

По нескольким причинам я не могу использовать сильный тип, такой как Member, в качестве входных данных для этого метода. Я должен использовать ExpandoObject.

  • Используемая версия MySql - 5.7.13
  • Моя версия Dapper - 1.60.6
  • MySql.Data. Я использую пакет nuget 8.0.17

1 Ответ

1 голос
/ 08 октября 2019

ОК, я основываюсь на теории, которую мы обсуждали выше. Я бы расширил ваши DynamicParameters, чтобы вы также передавали DBType значения.

Например: (источник: https://dapper -tutorial.net / parameter-dynamic )

parameter.Add("@Kind", InvoiceKind.WebInvoice, DbType.Int32, ParameterDirection.Input);
parameter.Add("@Code", "Many_Insert_0", DbType.String, ParameterDirection.Input);
parameter.Add("@RowCount", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue);

Итак, в вашем случае это может быть что-то вроде:

public async Task AddMember(ExpandoObject expando)
{
    var sql = "INSERT INTO MEMBERS(Salutation, FirstName, LastName) VALUES(@salutation, @firstName, @lastName)";

    // Convert the incoming ExpandoObject to Dapper's DynamicParameters
    // /7621957/kak-dinamicheski-sozdavat-argumenty-dlya-dapper-zaprosa
    if (expando != null)
    {
        var dbArgs = new DynamicParameters();

        foreach (var param in expando)
        {
            dbArgs.Add(param.Key, param.Value, DbType.String, ParameterDirection.Input);
        }

        await mySqlConnection.ExecuteAsync(sql, dbArgs);
    }
}

Я понимаю, что это немного умаляет динамический способ, которым вы пытаетесь это сделать (имеятип и направление жестко заданы), но вы можете добавить к исходному Expando, чтобы это значение можно было установить и передать в метод AddMember.

...