Postgresql与postGIS和entity framework,CHECK约束问题

6
我有一个带有postGIS的postgresql数据库,我正在使用dotconnect 6.7 for postgreSQL的entity framework。下面是我的数据库中的一张表:
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、Entity Framework还是DotConnect中的一个bug吗?

编辑: 查询语句

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

返回的是SRID 0。所以,无论我在实体框架中指定什么SRID,在数据库中都显示为0。

发生了什么事?


postgresql 6.7?这根本不存在。(http://www.postgresql.org/support/versioning/)难道是dotconnect 6.7吗?那Postgres和PostGis版本是什么? - Erwin Brandstetter
修正措辞。PostgreSQL 9.2.4和PostGIS 2.0.3 r11132。 - user1815201
好的,至少在postgresql 9.1和postgis 1.5上,我们看到st_srid = 4326; 您需要使用查询日志并查看dotconnect输出的任何内容。 - Antti Haapala -- Слава Україні
我对postgis不是很了解,但三个约束条件都失败了,这表明st_srid可能返回null。 - maniek
不确定为什么如果st_srid评估为null,st_srid(the_geom)<= 4326会计算为true? - user1815201
2个回答

6

在.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 v6.7.287或更高版本后,导航到Visual Studio > Tools > Entity Developer > Options > Servers Options > PostgreSql并按下Reset按钮。这是必要的,以便将新的映射规则添加到您的Type Mapping Rules列表中:

  • 地理 (Server Type) -> Data.Spatial.DbGeography (.NET Type)
  • 几何 (Server Type) -> Data.Spatial.DbGeometry (.NET Type)

现在从模型中删除Geo实体,然后在Tools > Entity Developer > Database Explorer中从工具箱拖放geo表到图表面上。打开Tools > Entity Developer > Model Explorer,确保geomentry属性的类型为:

  • SSDL中的spatial_geometry
  • CSDL中的Geometry

保存模型。

将以下条目添加到您的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工具来启用对数据库活动的跟踪: 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() 处收到了“function st_geomfromewkt(unknown) does not exist”的错误提示。 我安装了PostGIS 2.0和1.0 RC3 SharpMap。 - user1815201
您是否按照我们的回复中提到的所有步骤进行操作?如果还没有解决问题,请向我们发送一个小的测试项目以重现错误:http://www.devart.com/company/contactform.html。 - Devart
我已经尽力按照所有步骤进行操作。测试项目已发送。 - user1815201
它在我们的环境中可以工作。您能否指定您收到的错误消息的确切文本?如果由于编码不匹配而导致错误文本格式不正确,请将“Unicode=true;”条目添加到连接字符串中(通过Tools > Entity Developer > Database Explorer > Edit Connection Properties),并保存模型以更新您的App.config。另外,请打开dbMonitor工具以查找未能执行的SQL语句。 - Devart
根据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)其中:p4为p4 Input VarChar SRID=4326;POINT(1 1) - user1815201
你是否在当前数据库中创建了postgis扩展? CREATE EXTENSION postgis; http://postgis.net/docs/manual-2.0/postgis_installation.html#create_new_db_extensions - Devart

1
如果问题出在约束条件上,我建议您重新创建表。在Postgis 2中,您可以使用类型化几何体。尝试使用这样的表格。
CREATE TABLE geo 
(
  the_geom geometry(POINT,4326), -- the constraints are here --
  id integer NOT NULL
);

为了更好地响应,请将失败查询返回的数据库SQLSTATE代码放置在适当位置。

我没有使用框架的经验。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接