Existe-t-il une classe intégrée dans le framework .Net qui peut être utilisée pour désigner une AnsiString ?

StackOverflow https://stackoverflow.com/questions/6069021

  •  07-09-2020
  •  | 
  •  

Question

Pour plus pimpant, j'ai besoin de créer un support pour la transmission des paramètres AnsiString.

Les bases de données contiennent à la fois des chaînes Unicode et non Unicode, il est parfois crucial de choisir le bon type de paramètre.

DbType.String contre DbType.AnsiString car un paramètre particulier peut affecter considérablement les performances.

Dans Dapper, nous passons les paramètres de manière dynamique, par exemple :

Query<User>("select * from Users where Name=@Name", new {Name = "name"});

J'ai une carte interne qui dit que si je vois typeof(String) Je sais qu'il faut passer le paramètre en tant que DbType.String

Cependant, j'aimerais que mes utilisateurs puissent indiquer que la chaîne doit être une AnsiString.Les attributs ne sont pas pris en charge pour les classes anonymes, j'ai donc besoin d'un type distinct pour cela.

Clairement, je peux en inventer un :

public class AnsiString 
{
    private readonly string str;
    public AnsiString(string str)
    {
        this.str = str;
    }

    public String Value { get { return str; } }
}

Ce qui me donnerait l'API propre :

Query<User>("select * from Users where Name=@Name", 
   new {Name = new AnsiString("name")});

Cependant, pourquoi en inventer une si une telle classe existe dans System.Data ou la BCL.

Y a-t-il un type quelque part dans la BCL ou System.Data Je pourrais l'utiliser comme conteneur pour AnsiString, avec une sémantique similaire à l'exemple ci-dessus ?

Était-ce utile?

La solution

Il n’existe pas une telle classe dans la BCL ou System.Data, vous devrez créer la vôtre.

Nous avons opté pour un type personnalisé pour fournir une personnalisation plus fine au final ;ce test montre une utilisation typique :

public void TestDbString()
{
    var obj = connection.Query("select datalength(@a) as a, datalength(@b) as b, datalength(@c) as c, datalength(@d) as d, datalength(@e) as e, datalength(@f) as f",
        new
        {
            a = new DbString { Value = "abcde", IsFixedLength = true, Length = 10, IsAnsi = true },
            b = new DbString { Value = "abcde", IsFixedLength = true, Length = 10, IsAnsi = false },
            c = new DbString { Value = "abcde", IsFixedLength = false, Length = 10, IsAnsi = true },
            d = new DbString { Value = "abcde", IsFixedLength = false, Length = 10, IsAnsi = false },
            e = new DbString { Value = "abcde", IsAnsi = true },
            f = new DbString { Value = "abcde", IsAnsi = false },
        }).First();
    ((int)obj.a).IsEqualTo(10);
    ((int)obj.b).IsEqualTo(20);
    ((int)obj.c).IsEqualTo(5);
    ((int)obj.d).IsEqualTo(10);
    ((int)obj.e).IsEqualTo(5);
    ((int)obj.f).IsEqualTo(10);
}

Donc;Elle supporte:

  • ansi contre unicode
  • longueur fixe ou dynamique
  • dans le cas d'une longueur dynamique, explicite vs implicite (4 000 si la longueur est <= 4 000 ;"max" sinon - cela maintient le nombre de plans de requête raisonnable)

Le type est disponible à l'intérieur pimpant.

Autres conseils

Je suppose que tu peux utiliser string pour DbType.String et char[] pour DbType.AnsiString.

Il ressemblera beaucoup à votre code actuel :

Query<User>("select * from Users where Name=@Name", new {Name = "name".ToCharArray()});

Ou si vous souhaitez utiliser votre AnsiString, vous pouvez créer une méthode d'extension .ToAnsiString():

public static AnsiString( this string s ) { return new AnsiString(s); }
Query<User>("select * from Users where Name=@Name", new {Name = "name".ToAnsiString()});
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top