studio - Creando mapeo ADO.NET para tipo personalizado
visual studio installer (3)
Tengo un tipo personalizado que he creado, que debe conservarse en una base de datos (en este caso, servidor SQL) como guid (aunque esta pregunta es igual de válida para un objeto que podría almacenarse como una cadena, un entero, etc.) .
Cuando paso este tipo como un parámetro a un objeto DbCommand, obtengo una excepción:
ArgumentException: no existe una asignación del tipo de objeto [...] a un tipo nativo de proveedor gestionado conocido.
Tengo operadores CType en la clase que permiten la conversión implícita a una cadena, o un guid, pero .NET no los utiliza, ya que no sabe que debe convertir el tipo.
¿Hay alguna manera de agregar un tipo a la asignación interna, o decirle a .NET cómo almacenar mi tipo personalizado en la base de datos?
Obviamente, puedo convertir el tipo al pasarlo a .NET, pero me gustaría que esto suceda automáticamente, como lo hace para la mayoría de los tipos incorporados.
Intenté implementar una clase TypeConverter para mi tipo (hereda de TypeConverter, reemplaza CanConvertFrom, CanConvertTo, ConvertFrom, ConvertTo, IsValid y agregó el atributo System.ComponentModel.TypeConverter a mi clase), pero esto aún no funciona.
Asumo que falta una pieza que indique a .NET a qué tipo convertir cuando se almacena el valor en la base de datos.
Mi solución para esto, por ahora, es interceptar la lista de parámetros, antes de pasarlos al servidor SQL, y tener un método que cambie mi tipo personalizado en un guid. Esto es sucio, pero funciona por ahora, pero sigo pensando que esta pregunta no ha sido respondida.
Aquí hay algunos enlaces a Type Converters en .Net
Para resolver el problema creado la interfaz:
public interface ICustomDbValue
{
object Value { get; }
}
y lo implementé para mi tipo personalizado. También envolví la creación de comandos SQL por una función donde funciona el siguiente código:
...
IDbCommand command = connection.CreateCommand();
...
ICustomDbValue customParam = rawData as ICustomDbValue;
object value = customParam != null ? customParam.Value : rawData;
IDataParameter parameter = command.CreateParameter();
parameter.Value = value ?? DBNull.Value;
...
Todo lo que tengo que hacer es utilizar esta función e implementar ICustomDbValue para mis tipos. Casi parece usar atributos.
De acuerdo con ¿Cómo debo pasar un tipo definido por el usuario a SqlParameterCollection.AddWithValue? , no es posible. También analicé el método GetMetaTypeFromValue, y parece que de hecho toda la asignación está codificada en el marco, por lo que no es posible realizar una asignación definida por el usuario.
Qué molesto, sería realmente útil tener un atributo que defina el mapeo para un tipo dado.