¿Existe una clase incorporada en el marco .Net que pueda usarse para indicar un AnsiString?
-
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?
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()});