【问题标题】:Postgresql with postGIS and entity framework, CHECK constraint issuePostgresql 与 postGIS 和实体框架,CHECK 约束问题
【发布时间】:2013-07-29 10:33:12
【问题描述】:

我有一个带有 postGIS 的 postgresql 数据库,我正在使用带有 dotconnect 6.7 的实体框架用于 postgreSQL。

在我的数据库中有下表:

CREATE TABLE geo 
(
  the_geom geometry,
  id integer NOT NULL,
  CONSTRAINT primary_key PRIMARY KEY (id),
  CONSTRAINT enforce_srid_geometry CHECK (st_srid(the_geom) = 4326)
)

并运行以下代码

class Program {
    static void Main(string[] args) {
        using (test_Model.test_Entities ctx = new test_Model.test_Entities()) {
            var geom = new test_Model.geo();
            geom.id = 0;
            geom.the_geom = DbGeometry.PointFromText("POINT (1 1)", 4326).AsBinary();
            ctx.geos.AddObject(geom);
            ctx.SaveChanges();
    }
}

以下约束在数据库中失败

CONSTRAINT enforce_srid_the_geom CHECK (st_srid(the_geom) = 4326)

好奇数据库注册了什么值,我尝试了以下两个约束

CONSTRAINT enforce_srid_the_geom CHECK(st_srid(the_geom) > 4326)
CONSTRAINT enforce_srid_the_geom CHECK(st_srid(the_geom) < 4326)

都没有用。由于这些是要比较的整数值,因此最后三个查询中至少有一个应该为真。

一段时间后,我发现以下约束允许我将 srid=4326 的内容插入到表中

st_srid(the_geom) <= 4326)

但出于某种原因,它似乎接受了一切,无论是更大的还是更小的 srid。

这是 postgresql、实体框架或 dotconnect 中的错误吗?

编辑: 查询

SELECT st_srid(the_geom) FROM geo WHERE geo.id == 0

返回 srid 0。因此,无论我在实体框架中指定什么 srid,它在数据库中都显示为 0。 怎么回事?

【问题讨论】:

  • postgresql 6.7? Doesn't even exist. 还是那个 dotconnect 6.7?那么 Postgres 和 PostGis 的版​​本是什么?
  • 修正了措辞。 PostgreSQL 9.2.4 和 PostGis 2.0.3 r11132。
  • 好吧,至少在 postgresql 9.1 和 postgis 1.5 上,我们看到 st_srid = 4326;您想使用查询日志记录并查看 dotconnect 吐出的任何内容
  • 我对 postgis 了解不多,但所有失败的 3 个约束表明 st_srid 可能返回 null
  • 不知道为什么 st_srid(the_geom)

标签: entity-framework postgresql devart dotconnect


【解决方案1】:

.NET 端应该使用相应的几何类型而不是 byte[]:

  1. .NET 4.0 -> EntityFramework.dll v6 中的 System.Data.Entity.Spatial.DbGeometry
  2. .NET 4.5 -> System.Data.Entity.dll 中的 System.Data.Spatial.DbGeometry

您正在使用Entity Developer(Devart Entity Model 项目,*.edml),不是吗?

安装 dotConnect for PostgreSQL v 6.7.287(或更高版本)后,导航至 Visual Studio > 工具 > 实体开发人员 > 选项 > 服务器选项 > PostgreSql,然后按重置按钮。这是必要的,以便将新的映射规则添加到您的类型映射规则列表中:

  • geography(服务器类型)-> Data.Spatial.DbGeography(.NET 类型)
  • 几何(服务器类型)-> Data.Spatial.DbGeometry(.NET 类型)

现在从模型中删除 Geo 实体,然后将地理表从工具 > 实体开发人员 > 数据库资源管理器拖放到图表表面。打开 Tools > Entity Developer > Model Explorer 并确保 geomentry 属性的类型是:

  • SSDL 中的空间几何
  • CSDL 中的几何图形

保存模型。

将此条目添加到您的 app.config:

  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="GeoAPI" publicKeyToken="a1a0da7def465678" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-1.7.1.0" newVersion="1.7.1.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>

运行以下代码:

class Program {
    static void Main(string[] args) {

        // new Devart.Data.PostgreSql.PgSqlMonitor() { IsActive = true };

        var config = Devart.Data.PostgreSql.Entity.Configuration.PgSqlEntityProviderConfig.Instance;
        config.SpatialOptions.SpatialServiceType = Devart.Data.PostgreSql.Entity.Configuration.SpatialServiceType.NetTopologySuite;

        using (test_Model.test_Entities ctx = new test_Model.test_Entities()) {
            var geom = new test_Model.geo();
            geom.id = 0;
            geom.the_geom = DbGeometry.PointFromText("POINT (1 1)", 4326);
            ctx.geos.AddObject(geom);
            ctx.SaveChanges();
    }
}

我们建议使用dbMonitor tool 来启用对数据库活动的跟踪:http://www.devart.com/dotconnect/postgresql/docs/?dbmonitor.html

附加信息:

  1. 你项目中SharpMap的版本应该是1.0 RC3 (http://sharpmap.codeplex.com/releases/view/106717)。 1.0决赛 dotConnect for PostgreSQL 即将支持该版本
  2. 请使用 2.0(或更高)版本的 Postgis。你可以检查 通过在数据库中执行“select postgis_version()”得到版本

相应的 Devart 文档可在 http://blogs.devart.com/dotconnect/enhanced-entity-framework-spatials-support-for-oracle-mysql-and-postgresql.html 获得。

这有帮助吗?

【讨论】:

  • 嗯,我在 context.SaveChanges() 中得到“函数 st_geomfromewkt(unknown) 不存在”。我有 postgis 2.0 和 1.0 RC3 SharpMap。
  • 您是否按照我们回复中的所有步骤进行操作?如果这没有帮助,请给我们发送一个小测试项目来重现错误:devart.com/company/contactform.html
  • 我确实尽我所能遵循了所有步骤。测试项目已发送。
  • 它适用于我们的环境。您能否指定您收到的错误消息的确切文本?如果由于编码不匹配而导致错误文本格式错误,请添加“Unicode=true;”输入您的连接字符串(通过工具 > 实体开发人员 > 数据库资源管理器 > 编辑连接属性)并保存模型以更新您的 App.config。另外请打开dbMonitor工具查找执行失败的SQL语句。
  • 根据dbMonitor,错误是“函数st_geomfromwkt(unknown)不存在。失败的查询是INSERT INTO x.y(x, y, start_datetime, end_datetime, the_geom) VALUES (:p0, :p1, :p2, :p3, ST_GeomFromEWKT(:p4)) RETURNING idadapter) where :p4 is p4 Input VarChar SRID=4326;POINT(1 1)
【解决方案2】:

如果问题是这些限制,我建议您重新创建表。在 Postgis 2 中,您可以使用类型化几何。 尝试使用这样的表格

CREATE TABLE geo 
(
  the_geom geometry(POINT,4326), -- the constraints are here --
  id integer NOT NULL
);

您应该放置从失败查询返回的数据库 SQLSTATE 代码以提供更好的响应。

我没有使用过框架的经验。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-13
    • 1970-01-01
    相关资源
    最近更新 更多