¿Existe una clase incorporada en el marco .Net que pueda usarse para indicar un AnsiString?

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

  •  07-09-2020
  •  | 
  •  

Pregunta

Para ser elegante, necesito crear soporte para pasar parámetros AnsiString.

Las bases de datos tienen cadenas Unicode y no Unicode, por lo que a veces es crucial elegir el tipo de parámetro correcto.

DbType.String vs DbType.AnsiString para un parámetro en particular puede afectar en gran medida el rendimiento.

En dapper pasamos parámetros dinámicamente, por ejemplo:

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

Tengo un mapa interno que dice que si veo typeof(String) Sé pasar el parámetro como DbType.String

Sin embargo, me gustaría que mis usuarios pudieran indicar que la cadena debe ser AnsiString.Los atributos no son compatibles con clases anónimas, por lo que necesito un tipo distinto para esto.

Claramente puedo inventar uno:

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

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

Lo que me daría la API limpia:

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

Sin embargo, ¿por qué inventar una si dicha clase existe en System.Data o BCL?

¿Existe algún tipo en algún lugar del BCL o System.Data Podría usarlo como contenedor para AnsiString, con una semántica similar a la del ejemplo anterior?

¿Fue útil?

Solución

No existe tal clase en BCL o System.Data, tendrá que crear la suya propia.

Optamos por un tipo personalizado para proporcionar una personalización más detallada al final;esta prueba muestra un uso típico:

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);
}

Entonces;soporta:

  • ansi vs unicode
  • longitud fija versus dinámica
  • en el caso de longitud dinámica, explícito versus implícito (4000 si la longitud es <= 4000;"max" en caso contrario: esto mantiene el número de planes de consulta en orden)

El tipo está disponible en el interior. apuesto.

Otros consejos

Supongo que puedes usar string para DbType.String y char[] para DbType.AnsiString.

Se verá muy similar a su código actual:

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

O si desea utilizar su AnsiString, puede crear un método de extensión .ToAnsiString():

public static AnsiString( this string s ) { return new AnsiString(s); }
Query<User>("select * from Users where Name=@Name", new {Name = "name".ToAnsiString()});
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top