【问题标题】:sql geography to dbgeography?sql地理到dbgeography?
【发布时间】:2013-02-27 09:05:26
【问题描述】:

也许我错过了什么。我有一个“地理”数据类型的 sql server 列。

我想在我的 c# 代码中使用 DbGeography 类型。有什么方法可以将 sql 的 geography 转换为 dbgeography?

【问题讨论】:

    标签: sql-server c#-4.0 gis geospatial spatial


    【解决方案1】:

    很抱歉回复晚了 - 但在搜索其他内容时看到了这个。

    只需执行以下操作:

    SqlGeography theGeography;
    int srid = 4326; // or alternative
    
    DbGeography newGeography = DbGeography.FromText(theGeography.ToString(), srid);
    

    反转它:

    DbGeography theGeography;
    SqlGeography newGeography = SqlGeography.Parse(theGeography.AsText()).MakeValid();
    

    希望有帮助!

    【讨论】:

    • 我实际上正在另一个项目中再次出现这种情况,所以谢谢,正是我想要的。
    • 我已经多次看到此推荐,但在 .NET 中使用时,MakeValid 方法似乎不适用于 SqlGeography 类型。我错过了什么吗?
    • @jm2 如果你引用了 Microsoft.SqlServer.Types 它应该对你可用。
    • @JonBellamy 我有。带有运行时 v2.0.50727 的程序集 v10.0.0.0。 SqlGeometry 和 SqlGeography 类型可用,SqlGeometry 有 MakeValid,SqlGeography 没有。也许引用错误的版本?这可能最适合另一个问题。
    • 对于后代,“MakeValid”问题是 SQL Server 版本的问题。据我所知,在 SQL Server 2012 版之前,MakeValid 不是 SqlGeography 类型的函数。因此,如果安装了 SQL Server 的早期版本,即使在引用 Microsoft.SqlServer 时,MakeValid 函数在 .NET 应用程序中也将不可用。类型。我不知道在不更新 SqlServer 版本的情况下更新程序集版本的方法。也许您可以从某个地方获取 dll 并将其添加到 GAC,但我想这会导致副作用。
    【解决方案2】:

    当性能很重要时,应该使用众所周知的二进制而不是众所周知的文本:

    var newGeography = DbGeography.FromBinary(theGeography.STAsBinary().Value);
    

    使用 SRID 会导致过载,如果这很重要的话。在我对 1000 个相当复杂的多边形的简单测试中,基于二进制的方法比基于文本的方法快 4 倍:

    * Binary-based conversion
    Run 1: 1948
    Run 2: 1944
    Run 3: 1959
    Run 4: 1979
    Run 5: 1988
    Average: 1963.6
    
    * Text-based conversion
    Run 1: 8527
    Run 2: 8553
    Run 3: 8596
    Run 4: 8535
    Run 5: 8496
    Average: 8541.4
    

    【讨论】:

    • 反向操作:SqlGeography.STGeomFromWKB(new SqlBytes(value.AsBinary()), value.CoordinateSystemId)
    【解决方案3】:

    如果您没有运行 EF6,则提供的解决方案似乎没问题。 使用早期版本没问题,但是使用 EF6,我们不应该引用这个程序集。 这让 EF 有点疯狂。

    【讨论】:

    • 你能说得更具体点吗?究竟会发生什么,正确的解决方案是什么?
    • 对于其他阅读本文的人,我仍然使用我提供的 EF6 解决方案,但存在 个问题。
    【解决方案4】:

    您必须添加对上述程序集的引用。 以下帖子可能对您有所帮助link,link2

    【讨论】:

      【解决方案5】:

      根据我在 ILSpy 中对 EntityFramework.SqlServer.dll 的阅读,我认为从 SqlGeography 转换为 DbGeography 的最快方法是:

      var dbGeo = System.Data.Entity.SqlServer.SqlSpatialServices.Default.GeographyFromProviderValue(sqlGeo);
      

      这种方法的优点是不需要二进制转换和解析。它只是使用 SqlGeography 作为内部提供程序值返回一个 DbGeography。

      【讨论】:

        【解决方案6】:

        我发现这是一个可行的解决方案:

        int coordSys = DbGeography.DefaultCoordinateSystemId; // 4326; 
        SqlGeography g = SqlGeography.Point(lat, lon, coordSys);
        return DbSpatialServices.Default.GeographyFromProviderValue(g);
        

        没有序列化/转换为会降低性能的字符串 (WKT) 或二进制 (WKB)。

        它在 EF 6.1.3、SqlServer 2016 SP1 和 Microsoft.SqlServer.Types.14.0.314.76 上为我工作

        【讨论】:

        • 我要补充一点,如果你使用的 SqlGeography 大于 v10 (SQL 2008),那么这个方法会抛出一个错误,这意味着如果你需要 SQL 2012 及更高版本的任何特性,你'重新搞砸了。不过性能不错。
        • 我会假设也没有反向方法?
        • 应该有反向的方法。目前无法判断。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-13
        • 2023-03-27
        • 2014-12-06
        • 1970-01-01
        • 1970-01-01
        • 2014-08-15
        相关资源
        最近更新 更多