Невозможно сопоставить столбец SQL Geography с классом EF DbGeography с помощью dapper

У меня есть таблица со столбцом SQL географии в моей базе данных SQL. Я создал объекты для своей базы данных с EF6. Как вы знаете, Entitiy Framework генерирует System.Data.Entity.Spatial.DbGeography для типа географии SQL. Я использую dapper для запуска запросов и отображения результатов в мои EF-объекты.

Мой класс сущности

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

SQL-запрос, который выдает исключение

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

Вот снимок исключения

Я думаю, что по умолчанию dapper пытается сопоставить с Microsoft.SqlServer.Types.SqlGeography,

Есть ли обходной путь здесь?

РЕДАКТИРОВАНИЕ

Нашел какое-то решение, создал частичный класс для моей сущности

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

И изменил мой запрос

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

2 ответа

Если вы действительно хотите использовать Dapper, вы можете конвертировать SqlGeography в DbGeography:

DbGeography.FromText(sqlGeo.ToString());

Так что просто сделайте преобразование в памяти, или вы также можете просто использовать SQL с 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();

или просто использовать Entity Framework нормальным способом? Так как это не сложный запрос:)

dbContext.Fixes.Find(fixId);

Мне все еще любопытно, почему вы запрашиваете с Dapper, чтобы затем сопоставить его с сущностями из EF

Dapper имеет встроенную поддержку многих распространенных типов данных, но не всех. Вы можете рассмотреть возможность использования пользовательского параметра запроса - вы можете увидеть, как из этого коммита, который добавляет пользовательскую поддержку для параметров с табличным значением, можно DataTable, Я бы очень неохотно добавил что-либо, что требует дополнительных зависимостей, особенно для таких вещей, как EF. Что может быть полезно в будущем, это настраиваемый инструмент регистрации для пользовательских провайдеров (позволяющий данным в параметрах быть чем угодно - перемещаться туда, где происходит карта). Это не существует сегодня, хотя.

Другие вопросы по тегам