【问题标题】:EF5, SQL Server, Longitude and LatitudeEF5、SQL Server、经度和纬度
【发布时间】:2013-02-08 23:54:33
【问题描述】:

我发现在 SQL Server 中存储 lat 和 long 的最佳类型是十进制 (9,6)(参考 What datatype to use when storing latitude and longitude data in SQL databases?),所以我做到了

AddColumn("dbo.Table", "Latitude", c => c.Decimal(nullable: false, precision: 9, scale: 6));
AddColumn("dbo.Table", "Longitude", c => c.Decimal(nullable: false, precision: 9, scale: 6));

SQL 似乎没问题,一切正常,但是当我插入/更新一个值时,即

lat = 44.5912853

它是这样保存的:

44.590000

我检查了流程,就在更新之前,我的实体包含正确的值,所以我认为这与我的代码无关,而是与 EF / SQL 所做的某个回合有关。你有什么办法避免这种情况吗?

更新

update [dbo].[Breweries]
set [RankId] = @0, 
[Name] = @1, 
[Foundation] = null, 
[DirectSale] = @2, 
[OnlineSale] = @3, 
[StreetAddress] = @4, 
[StreetAddress1] = null, 
[ZIP] = @5, 
[City] = @6, 
[Province] = @7, 
[CountryCode] = @8, 
[Latitude] = @9, 
[Longitude] = @10, 
[PIVA] = null, 
[CodFiscale] = null
where ([BreweryId] = @11)

POCO 实体

[Table("Breweries")]
public class Brewery : ABrewery 
{
  ....
  public decimal Latitude { get; set; }
  public decimal Longitude { get; set; }
}

SQL 探查器

exec sp_executesql N'update [dbo].[Breweries]
set [RankId] = @0, [Name] = @1, [Foundation] = null, [DirectSale] = @2, [OnlineSale] = @3, [StreetAddress] = @4, [StreetAddress1] = null, [ZIP] = @5, [City] = @6, [Province] = @7, [CountryCode] = @8, [Latitude] = @9, [Longitude] = @10, [PIVA] = null, [CodFiscale] = null
where ([BreweryId] = @11)
',N'@0 int,@1 nvarchar(128),@2 bit,@3 bit,@4 nvarchar(256),@5 varchar(16),@6 nvarchar(64),@7 nvarchar(64),@8 nvarchar(128),@9 decimal(18,2),@10 decimal(18,2),@11 int',@0=2,@1=N'Davide',@2=0,@3=0,@4=N'Via Moscardini, 24',@5='zip',@6=N'city',@7=N'province',@8=N'ITA',

@9=44.59,@10=11.05,@11=2

谢谢

【问题讨论】:

    标签: c# asp.net-mvc-4 entity-framework-5 latitude-longitude


    【解决方案1】:

    显然this guy had the exact same problem 并因此解决了它:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Activity>().Property(a => a.Latitude).HasPrecision(18, 9);
        modelBuilder.Entity<Activity>().Property(a => a.Longitude).HasPrecision(18, 9);
    }
    

    尽管您可能希望考虑在 SQL Server 2008 及更高版本中使用spatial data types(尤其是geography)。

    【讨论】:

    • 我看到了“HasPrecision”,但是即使我添加了命名空间,当我尝试使用它时也会出现错误(找不到方法)
    • Property好吗?
    • 是的,intellisense 都没有找到它.. 我认为这是一个旧版本,我尝试了不同的.. 但我会再试一次,为什么我没有这个道具。
    • 找到了!并解决..我不知道为什么,我有一个单独的项目来收集所有的EntityTypeConfiguration(这可能没用,但我觉得更有条理)..在这个项目中没有找到HasPrecision(我会调查并报告这里为什么)..但是如果我在数据上下文中设置属性,我可以做到..并解决问题
    • 我想说你可能不得不把它从Primitive... 转换成Decimal... msdn.microsoft.com/en-us/library/…
    【解决方案2】:

    您可以使用DbGeography类型来存储纬度和经度。

    using System.Data.Entity.Spatial;
    
    public class Test
    {
        public DbGeography Location { get; set; }
    }
    

    【讨论】:

      【解决方案3】:

      两件事:

      1. 我刚刚购买了一个邮政编码数据库,它将所有纬度和经度值存储为十进制(12,6)数据类型。不过,我认为这不会从根本上改变您的结果。

      2. 我会检查发送到您的 SQL Server 的确切 SQL。然后,您可以检查四舍五入的位置。您可以通过从 EF 获取输出或使用 SQL Profiler 来检查正在发送的 SQL。我的猜测是它发生在您的 C# 代码中。

      此外,查看表架构和域实体可能很有用。

      【讨论】:

      • 我发布了 db 表的屏幕截图以及我在 Intellitrace 中看到的内容(我认为不是很有用,如果你告诉我如何更好地获取 EF 的输出,我会发布它)跨度>
      • 你的 C# 实体呢?
      • 我可以分析,如您所见,值在更新之前已经四舍五入
      • 使用模型构建器配置中的 HasPrecision 方法进行修复。但无论如何谢谢你:)
      【解决方案4】:

      使用这些字段的数据类型为浮点数:

       Latitude float,
       Longitude float
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-02-13
        • 2014-12-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-09
        • 2013-02-21
        • 1970-01-01
        相关资源
        最近更新 更多