No se puede asignar una columna de Geografía SQL a la clase EF DbGeography con dapper

c# dapper entity-framework sql sqlgeography

Pregunta

Tengo una tabla con una columna de geografía sql en mi base de datos SQL. He generado entidades para mi base de datos con EF6. Como ya sabe Entitiy Framework genera System.Data.Entity.Spatial.DbGeography para SQL Geography type. Estoy usando dapper para ejecutar consultas y asignar los resultados a mis entidades EF generadas.

Mi clase de entidad

public partial class Fix
{
    public Fix()
    {
        this.FixUsers = new HashSet<FixUser>();
    }

    public long FixID { get; set; }
    public long UserID { get; set; }
    public System.Data.Entity.Spatial.DbGeography Position { get; set; }
    public int Radius { get; set; }
    public System.DateTime CreatedDate { get; set; }

    public virtual MemberProfile MemberProfile { get; set; }
    public virtual ICollection<FixUser> FixUsers { get; set; }
}

Consulta SQL que lanza una excepción

    var fix = SqlConnection.Query<Fix>(@"SELECT TOP(1) 
                                         f.FixID as FixID, 
                                         f.UserID as UserID, 
                                         f.Radius as Radius, 
                                         f.CreatedDate as CreatedDate, 
                                         f.Position as Position
                                         FROM [Fix] f 
                                         WHERE f.FixID = @fixId", new { fixId }).FirstOrDefault();

Aquí hay una instantánea de excepción

enter image description here

Creo que por defecto dapper está tratando de mapear a Microsoft.SqlServer.Types.SqlGeography .

¿Hay alguna solución aquí?

EDITADO

Encontré alguna solución, creé una clase parcial para mi entidad

public partial class Fix
{
    public string PositionString
    {
        set
        {
            Position = DbGeography.PointFromText(value, 4326);
        }
    }
}

Y cambió mi consulta

var fix = SqlConnection.Query<Fix>(@"SELECT TOP(1) 
                                     f.FixID as FixID, 
                                     f.UserID as UserID, 
                                     f.Radius as Radius, 
                                     f.CreatedDate as CreatedDate, 
                                     f.Position.ToString() as PositionString
                                     FROM [Fix] f 
                                     WHERE f.FixID = @fixId", new { fixId }).FirstOrDefault();

Respuesta experta

Dapper tiene soporte incorporado para muchos tipos de datos comunes, pero no todos. Puede considerar usar un parámetro de consulta personalizado: puede ver cómo a partir de este compromiso, que agrega soporte personalizado para los parámetros de tabla como DataTable . Sería muy reacio a agregar cualquier cosa que exija dependencias adicionales, especialmente para cosas como EF. Lo que quizás sea útil en el futuro es una herramienta de registro personalizable para proveedores personalizados (lo que permite que los datos en los parámetros sean cualquier cosa, moviéndose donde sucede el mapa). Esto no existe hoy sin embargo.


Respuesta popular

Si realmente quieres usar Dapper, puedes convertir SqlGeography en DbGeography:

DbGeography.FromText(sqlGeo.ToString());

Así que solo haga la conversión en memoria, o también puede usar SQL con EF:

dbContext.Fixes.SqlQuery("SELECT TOP(1) 
                                     f.FixID, 
                                     f.UserID, 
                                     f.Radius, 
                                     f.CreatedDate, 
                                     f.Position
                                     FROM [Fix] f 
                                     WHERE f.FixID = @fixId", new SqlParameter("fixId", fixId)).FirstOrDefault();

o simplemente usa Entity Framework de la manera normal? Ya que no es una consulta complicada :)

dbContext.Fixes.Find(fixId);

Todavía tengo curiosidad de por qué consulta con Dapper para luego asignarlo a Entidades de EF



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué