Невозможно сопоставить столбец 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. Что может быть полезно в будущем, это настраиваемый инструмент регистрации для пользовательских провайдеров (позволяющий данным в параметрах быть чем угодно - перемещаться туда, где происходит карта). Это не существует сегодня, хотя.