无法使用dapper将SQL Geography列映射到EF DbGeography类

时间:2014-06-04 06:47:30

标签: c# sql entity-framework dapper sqlgeography

我的SQL数据库中有sql geography列表。我用EF6为我的数据库生成了实体。如您所知,Entitiy Framework为SQL Geography类型生成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();

这是异常快照

enter image description here

我认为默认情况下,dapper会尝试映射到Microsoft.SqlServer.Types.SqlGeography

这里有解决方法吗?

EDITED

找到一些解决方案,为我的实体创建了部分类

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 个答案:

答案 0 :(得分:0)

如果您真的想使用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();

或者只是正常使用Entity Framework?因为它不是一个复杂的查询:)

dbContext.Fixes.Find(fixId);

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

答案 1 :(得分:0)

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