Npgsql 3.0.0 Chokes sur les requêtes avec des paramètres ayant des gestionnaires de type personnalisés dans Dapper 1.42

c# dapper npgsql postgresql

Question

Ce problème semble être avec quelque chose dans Npgsql 3.0.0 qui a changé sous Dapper 1.42. Je suis arrivé à cette conclusion puisque le code suivant fonctionnait lors de l'utilisation de Npgsql 2.2.3 avec la même version de Dapper:

public struct MyStruct
{
    private readonly int _val;
    public MyStruct(int i) { _val = i; }
    public int MyInt { get { return _val; } }
}



public class MyStructHandler : SqlMapper.TypeHandler<MyStruct>
{
    public override MyStruct Parse(object value)
    {
        if (value is int)
        {
            return new MyStruct((int)value);
        }
        throw new FormatException("Invalid Conversion to MyStruct");
    }

    public override void SetValue(IDbDataParameter parameter, MyStruct value)
    {
        parameter.DbType = DbType.Int32;
        parameter.Value  = value.MyInt;
    }
}



public static int Main()
{
    var myStructHandler = new MyStructHandler();
    SqlMapper.AddTypeHandler(myStructHandler);

    const string query = "SELECT * FROM MyTable WHERE ID = :someID";
    var queryParams = new DynamicParameters();
    queryParams.Add("someID", new MyStruct(3));
    IDbConnection connection = new NpgsqlConnection(connectionString);
    var result = connection.Execute(query, queryParams);
}

Lorsque je lance le code ci-dessus, je reçois une exception avec le message:

Problème avec la requête: SELECT * FROM MyTable WHERE ID =: someID
La clé donnée n'était pas présente dans le dictionnaire
System.Collections.Generic.KeyNotFoundException: la clé donnée n'était pas présente dans le dictionnaire.

J'ai vérifié ce qui suit:

1) Le passage des paramètres des types intégrés fonctionne correctement. Par exemple, si je change la ligne queryParams.Add("someID", new MyStruct(3)); à queryParams.Add("someID", 3); , la requête retourne comme prévu.
2) MyStructHandler.Parse fonctionne correctement lors de la désérialisation d'un champ de type MyStruct
3) Le nom du paramètre et le casse correspondent à la requête et à l'objet DynamicParams
4) MyStructHandler.SetValue n'est jamais appelé avant de lancer l'exception

Ce bogue semble être nouvellement introduit et semble seulement affecter les classes avec des gestionnaires Dapper personnalisés. Est-ce que quelqu'un sait pourquoi cela a cessé de fonctionner une fois mis à niveau vers Npgsql 3.0.0, et plus important encore, comment le réparer?

- RENSEIGNEMENTS ADDITIONNELS -

L'exception est renvoyée dans Npgsql.NpgsqlParameter.set_DbType (valeur DbType), où il existe un appel à System.Collections.Generic.Dictionary`2.get_Item (clé TKey). Encore une fois, cela fonctionnait dans Npgsql 2.2.3, donc je suppose que quelque chose a changé dans ce code qui a cassé ce cas d'utilisation.

Réponse acceptée

Ce problème a déjà été signalé et corrigé, voir https://github.com/npgsql/npgsql/issues/694

Vous pouvez récupérer un paquet nuget instable pour résoudre ce problème immédiatement ( http://www.npgsql.org/install.html ) ou attendre encore quelques jours avant de publier Npgsql 3.0.1 avec ce correctif.



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi