【问题标题】:Cannot map SQL Geography column to EF DbGeography class with dapper无法使用 dapper 将 SQL 地理列映射到 EF DbGeography 类
【发布时间】:2014-06-04 06:47:30
【问题描述】:

我的 SQL 数据库中有带有 sql 地理列的表。我已经使用 EF6 为我的数据库生成了实体。如您所知,Entity Framework 为 SQL 地理类型生成 System.Data.Entity.Spatial.DbGeography。我正在使用 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();

【问题讨论】:

  • 将您的作品显示为文本,而不是图像..

标签: c# sql entity-framework dapper sqlgeography


【解决方案1】:

如果你真的想使用 Dapper,可以将 SqlGeography 转换为 DbGeography:

DbGeography.FromText(sqlGeo.ToString());

所以只需在内存中进行转换,或者您也可以只使用带有 EF 的 SQL:

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

或者只是以正常方式使用实体框架?因为这不是一个复杂的查询:)

dbContext.Fixes.Find(fixId);

我仍然很好奇你为什么用 Dapper 查询然后将其映射到 EF 中的实体

【讨论】:

  • 我使用 EF 只是为了为我的数据库生成实体。
  • @Mkrtich 是不是更简单,只是更改生成实体的类型? DbGeography 设计为与 EF 一起使用,而您正在使用 Dapper :) 也可以调整 T4 模板,您是否研究过?
  • @Mkrtich 还有其他的微型 ORM 附带 T4 模板来生成 pocos,例如,您可以使用 PetaPoco 的 T4 模板,而不是 EF 模板。 PetaPoco nuget package
【解决方案2】:

Dapper 内置了对许多常见数据类型的支持,但不是全部。您可能会考虑使用自定义查询参数 - 您可以从 this commit 中了解如何添加对表值参数的自定义支持为 DataTable。我非常不愿意添加任何需要额外依赖项的东西,尤其是对于像 EF 这样的东西。将来可能有用的是自定义提供程序的可自定义注册工具(允许参数中的数据是任何东西 - 移动地图发生的地方)。但今天不存在。

【讨论】:

  • 问题不在于传递参数,而在于从查询结果中获取数据。
  • @Mkritch 啊,澄清一下 - 我需要调查一下(目前在 NDC - 访问受限)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-15
  • 1970-01-01
  • 1970-01-01
  • 2011-08-19
相关资源
最近更新 更多