Mappage Enum à la colonne de chaîne avec SqlMapper.ITypeHandler - Dapper personnalisé

c# dapper enums orm

Question

J'ai un grand nombre de processus stockés PL / SQL qui renvoient des colonnes avec des chaînes de caractères uniques représentant une sorte de valeur d'état dans une plage fixe. Dans le projet sur lequel je travaille, ces colonnes ont été mappées par Dapper sur des propriétés de chaîne sur les objets du domaine, qui sont difficiles à gérer et peu fiables. Je voudrais donc passer aux énumérations.

Si j'ai utilisé des enum Foo {A, P} avec des noms simples comme enum Foo {A, P} je suis presque sûr que Dapper les mapperait correctement, mais je ne le veux pas, je veux des énumérations avec des étiquettes descriptives comme ceci:

enum Foo {
    [StringValue("A")]
    Active,
    [StringValue("P")]
    Proposed
}

Dans l'exemple ci-dessus, StringValueAttribute est un attribut personnalisé et je peux utiliser la réflexion pour convertir le "A" en Foo.Active , ce qui fonctionne Foo.Active - sauf que j'ai besoin que Dapper exécute cette logique de conversion pour moi. J'ai écrit un gestionnaire de type personnalisé pour faire ceci:

public class EnumTypeHandler<T> : SqlMapper.TypeHandler<T>
{
    public override T Parse(object value)
    {
        if (value == null || value is DBNull) { return default(T); }
        return EnumHelper.FromStringValue<T>(value.ToString());
    }

    public override void SetValue(IDbDataParameter parameter, T value)
    {
        parameter.DbType = DbType.String;
        parameter.Value = EnumHelper.GetStringValue(value as Enum);
    }
}

//Usage:
SqlMapper.AddTypeHandler(typeof(Foo),
    (SqlMapper.ITypeHandler)Activator.CreateInstance(typeof(EnumTypeHandler<>).MakeGenericType(typeof(Foo)));

L'enregistrement avec SqlMapper.AddTypeHandler() semble fonctionner DbConnection.Query() , mais lorsque mon code DbConnection.Query() s'exécute, je reçois une erreur indiquant que la valeur 'A' n'a pas pu être convertie - l'erreur est générée par Enum.Parse, ce qui suggère que Dapper n'appelle pas vraiment mon gestionnaire de fichiers malgré son enregistrement. Est-ce que quelqu'un sait comment contourner cela?

Réponse acceptée

Un autre utilisateur a signalé cela comme un problème sur le site github de Dapper. Il semble que ce soit une optimisation délibérée, spécifiquement autour des énumérations dans Dapper. J'ai donc changé mon modèle de base de données plutôt que d'essayer de changer le code de mappage. J'ai regardé essayer de modifier Dapper lui-même, mais le code source de Dapper est optimisé comme si je n'avais jamais vu, émettant des opcodes pour effectuer les conversions de la manière la plus performante possible. changements là-bas.



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