Tentative de modification de Dapper pour prendre en charge le type ntext de SQL Server CE

dapper sql-server-ce

Question

Je dois prendre en charge le type ntext de SQL Server CE dans Dapper. Il y a un fil ici décrivant le problème: https://code.google.com/p/dapper-dot-net/issues/detail?can=2&start=0&num=100&q=&colspec=ID%20Type%20Status%20Priority%20Milestone % 20Owner% 20Summary & groupby = & sort = & id = 110

J'ai tenté de modifier Dapper pour utiliser une solution similaire à l'approche utilisée dans PetaPoco: https://github.com/cyotek/PetaPoco/commit/ea13add473be3899ebb73b463d2aff98f8d6d06e

Après avoir jeté un coup d'œil à la source de Dapper, j'ai décidé que cela pourrait être de modifier la classe DbString . J'ai modifié la AddParameter(IDbCommand command, string name) (commençant à la ligne 3120) comme suit:

public void AddParameter(IDbCommand command, string name)
{
            if (IsFixedLength && Length == -1)
            {
                throw new InvalidOperationException("If specifying IsFixedLength,  a Length must also be specified");
            }
            var param = command.CreateParameter();
            param.ParameterName = name;
            param.Value = (object)Value ?? DBNull.Value;
            if (Length == -1 && Value != null && Value.Length <= 4000)
            {
                param.Size = 4000;
            }
            else
            {
                param.Size = Length;
            }
            param.DbType = IsAnsi ? (IsFixedLength ? DbType.AnsiStringFixedLength : DbType.AnsiString) : (IsFixedLength ? DbType.StringFixedLength : DbType.String);

            if (param.Value != null)
            {
                if (param.Value.ToString().Length + 1 > 4000 && param.GetType().Name == "SqlCeParameter")
                {
                    param.GetType().GetProperty("SqlDbType").SetValue(param, System.Data.SqlDbType.NText, null);  
                }
            }

            command.Parameters.Add(param);
}

Mon édition est la partie vers le bas qui vérifie le type et tente de la changer en ntext . Lorsque je lance ce code, cependant, IIS Express se bloque et asp.net ne me donne aucune information de débogage utile. J'ai essayé de l'exécuter dans un débogueur et je reçois une erreur liée à la corruption de tas.

Suis-je sur la mauvaise voie ici? Y a-t-il un meilleur moyen de tenter quelque chose comme ça dans Dapper? Ou est-ce quelque chose qui ne fonctionnera pas simplement à cause de la manière dont le cache et / ou l'IL est généré? J'espérais créer une demande de tirage si je pouvais le faire fonctionner, mais je riposte.


Mise à jour - J'ai trouvé une solution potentielle. J'ai ajouté du code à la AddParameters(IDbCommand command, SqlMapper.Identity identity) sur la classe DynamicParameters . Les dernières lignes de la méthode se lisent maintenant comme suit:

if (s != null)
{
    if (s.Length + 1 > 4000 && p.GetType().Name == "SqlCeParameter")    
    {
        p.GetType().GetProperty("SqlDbType").SetValue(p, SqlDbType.NText, null);
        p.Size = s.Length;
    }
}
if (add)
{
    command.Parameters.Add(p);
}
param.AttachedParam = p;

Pour utiliser cette solution, je dois ajouter mes paramètres en tant que DynamicParameters. Cela fonctionne donc, mais pas de la manière la plus utile. Je cherche toujours une meilleure solution.

Est-ce le genre de chose que les développeurs de Dapper envisageraient d'inclure en tant que patch si je crée une requête pull?

Réponse populaire

Essayez cette méthode d'extension pour n'importe quel sac de propriété:

    public static class DynamicParametersExtensions
{
    public static DynamicParameters AsDynamic(this object propertyBag) {
        var parameters = new DynamicParameters();
        foreach (var property in propertyBag.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)) {
            var propertyValue = property.GetValue(propertyBag);
            var propertyValueAsString = propertyValue as string;
            if (propertyValueAsString != null && propertyValueAsString.Length >= 4000) {
                parameters.Add(property.Name, new DbString {
                    Value = propertyValueAsString,
                    Length = propertyValueAsString.Length
                });
            } else {
                parameters.Add(property.Name, propertyValue);
            }
        }
        return parameters;
    }
}

Exemple d'utilisation:

connection.Execute(@"UPDATE MyTable SET NTextColumn=@NTextColumn", new { value.NTextColumn }.AsDynamic()); 



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