EF ( Entity Framework) 操作ArcCataLog 生成的(Sql Server)空间数据库
因为项目需求,现在需要利用EF 操作由Arccatalog生成的sql server空间数据库.。在此之前,一直没有接触过空间数据库,在操作空间数据库时 绕了许多弯。。。 因此写一篇随笔做一个总结。
首先,我们了解一下空间数据库:空间数据库是指地理信息系统在计算机物理存储介质上存储的与应用相关的地理空间数据的总和,一般是以一系列特定结构的文件的形式组织在存储介质之上的。 在微软的官方文档中,有详细关于空间数据的介绍 https://docs.microsoft.com/zh-cn/sql/relational-databases/spatial/spatial-data-types-overview .文档中提出空间数据库有两种空间数据类类型: 一、geometry 数据类型支持平面或欧几里得(平面球)数据。 geometry数据类型符合开放地理空间联盟 (OGC) 的 SQL 简单特征规范 1.1.0 版 并符合 SQL MM(ISO 标准)。二、 geography 数据类型,该数据类型可存储诸如 GPS 纬度和经度坐标之类的椭圆体(圆球)数据。 此次项目涉及的空间数据类型为 geography 数据类型。 关于如何从ArcCataLog生成sql server 空间数据库 ,可以参考百度:http://jingyan.baidu.com/article/72ee561a55ef57e16138dfa0.html.
其次,了解了空间数据库的基本概念,我们开始尝试操作空间数据库。
在sql server 中查看 由ArccataLog 生成的数据库 :库中含有许多表, 我们暂时仅需要操作一张点表(已经含有位置和其他属性,lon 为经度,lat 为纬度)名字为ALLPOINT。点开表的设计,我们发现它与一般的表的区别: : 1 主键ID为:OBJECTID(未设置为自增长). 2 多了字段:value. 3. 多了字段:Shape (Shape 内容为{Point(经度,纬度)}不过这个精度比lon lat 精度高)
在实际应用中,我们需要对点的经纬度进行修改,或者添加新点,这时涉及数据的更新和添加,当我尝试在sql server 中编辑 数据时,sql server 总是报错,不能完成修改工作,因此决定利用sql 语句进行操作。 在实际应用中,我们需要对点的经纬度进行修改,此时必须使用Sql 语句进行修改 ,在网上查了一些资料:微软官方文档:https://msdn.microsoft.com/zh-cn/library/cc280487(v=sql.120).aspx, 通过这个文档,尝试操作数据库。其中:查询 和删除数据与普通数据库操作无异.,区别主要在更新。
sql 语句更新数据
1 更新: update [dbo].[ALLPOINT] SET Shape=geometry::STGeomFromText('POINT (114.93247099983682 24.868304000429305)',4326), where OBJECTID=4
通过这个语句,我们可以选取出OBJECTID为4的数据,并对数据中Shape的值进行更新, 其中 Point括号内部为经纬度值, 4326 为坐标系编号(这里特别提示,必须输入与ArcCatalog 选择坐标系一致的坐标系,在sql server 中这个字段 有一个约束:经纬度坐标必须为4326 .之前仿造 微软文档 填 0,一直报错。 )
2 添加:INSERT INTO [dbo].[LNALLPOINT](OBJECTID,value,lat,lon,Shape) VALUES (2,2.0000,114.93247099983682,24.868304000429305,geometry::STGeomFromText('POINT (114.93247099983682 24.868304000429305)',4326))
通过以上两个sql 语句 我们可以轻松的完成数据的更新与添加.
EF中更新数据
但 在项目中,我采用了EF框架 ,现在问题变成了:如何通过EF 操作空间数据库。我们观察 由EF生成Model中点表的结构:
我们发现点表的shape字段 变成了 public System.Data.Entity.Spatial.DbGeometry Shape { get; set; } 这么一个属性 . 在微软官方文档查询相当资料:https://msdn.microsoft.com/en-us/library/system.data.entity.spatial.dbgeometry/html
为了检验Shape具体情况 ,通过程序调试我们发现 Shape 的类型为:
图1 图2
如图1所示,shape有许多方法和属性均有红叉, 值为:函数求值类型需要运行所有线程. 图2 有一个属性ProviderValue 内容为 点的经度 ,纬度 ,仰角等...看到这里, 我就想尝试 通过获取ProviderValue的值,然后修改值. 我们通过观察ProviderValue ,发现 ProviderValue 类型为:
针对这个类型, 再次查找微软官方文档:https://msdn.microsoft.com/en-us/library/microsoft.sqlserver.types.sqlgeometry.aspx, 不过很可惜,ProviderValue的 STX,STY 属性为只读属性,所以想通过修改Shape的ProviderValue的想法无法实现. 这时,重新审视了 sql server 修改Shape 的语句, 想sql 语句可以拼写一个Shape对象,那么 EF肯定也可以,所以 查找 文档,终于在System.Data.Entity.Spatial.DbGeometry 中发现了FromText方法,
根据官方提示,可以通过这个方法 创建一个DbGeometry .经过 尝试,终于 修改成功. 部分代码如下:
var id = point.OBJECTID;
//查询原始数据 ,将改变 的数据重新赋值
//特别 当点的经纬度改变 时 ,需要将Shape的经纬度进行改变
var monitorPointInfo = AllPointService.LoadEntities(u => u.OBJECTID == id && u.Deflag == ).FirstOrDefault();string shapeString = "";
if (monitorPointInfo.lon != point.lon || monitorPointInfo.lat != point.lat)
{
//当 点的经纬度改变 ,Shape的值也需要改变
monitorPointInfo.lon = point.lon;
monitorPointInfo.lat = point.lat;
shapeString = "POINT(";
shapeString += monitorPointInfo.lon + " " + monitorPointInfo.lat;
shapeString += ")";
//通过这个方法重新创建 shape 只修改了点经纬度部分 ,其他部分未进行修改, 暂时不知道其他影响
monitorPointInfo.Shape = System.Data.Entity.Spatial.DbGeometry.FromText(shapeString, );
}
在EF中 实现修改时 ,有一个比较坑的地方: 就是修改时,不能够再查一次当前数据, 不然会报错:System.InvalidOperationException:“附加类型“******.Model.ALLPOINT”的实体失败,因为相同类型的其他实体已具有相同的主键值。在使用 "Attach" 方法或者将实体的状态设置为 "Unchanged" 或 "Modified" 时如果图形中的任何实体具有冲突键值,则可能会发生上述行为。这可能是因为某些实体是新的并且尚未接收数据库生成的键值。在此情况下,使用 "Add" 方法或者 "Added" 实体状态跟踪该图形,然后将非新实体的状态相应设置为 "Unchanged" 或 "Modified"。” 关于这个错误 ,可以参考:http://www.ithao123.cn/content-3651827.html
总结:
跳了好多坑,终于是暂时解决了在EF下修改空间数据库中 Shape 属性。还好文档给力,也许还有其他更好 的方法来修改数据,暂时只能这么做....
EF ( Entity Framework) 操作ArcCataLog 生成的(Sql Server)空间数据库的更多相关文章
- Entity Framework中查看生成的SQL语句
Entity Framework 4.0 中是这样的,高版本的跟这个有些差异,不太一样,貌似已经到7了 using (Entities entities = new Entities()) { var ...
- Lerning Entity Framework 6 ------ Handling concurrency With SQL Server Database
The default Way to handle concurrency of Entity Framework is using optimistic concurrency. When two ...
- entity framework 查看自动生成的sql
public MesDbContext() : base("name=mysql") { Database.Log = new Action<string>(msg = ...
- Linq实战 之 Linq to Sql及Entity Framework操作详解
Linq实战 之 Linq to Sql及Entity Framework操作详解 一:linq to db的框架 1. linq to sql 2. linq to ado.net entity f ...
- [转载]灵动思绪EF(Entity FrameWork)
很久之前就想写这篇文章了,但是由于种种原因,没有将自己学习的EF知识整理成一片文章.今天我就用CodeFirst和ModelFirst两种方式的简单案例将自己学习的EF知识做个总结. 在讲解EF之前, ...
- EF(Entity Framework)多对多关系下用LINQ实现"NOT IN"查询
这是今天在实际开发中遇到的一个问题,需求是查询未分类的博文列表(未加入任何分类的博文),之前是通过存储过程实现的,今天用EF实现了,在这篇博文中记录一下. 博文的实体类BlogPost是这样定义的: ...
- EF(Entity Framework)通用DBHelper通用类,增删改查以及列表
其中 通用类名:DBhelper 实体类:UserInfo 1 //新增 2 DBHelper<UserInfo> dbhelper = new DBHelper<UserInfo& ...
- 解决VS2010在新建实体数据模型出现“在 .NET Framework Data Provider for Microsoft SQL Server Compact 3.5 中发生错误。请与提供程序供应商联系以解决此问题。”的问题
最近想试着学习ASP.NET MVC,在点击 添加--新建项--Visual C#下的数据中的ADO.NET 实体数据模型,到"选择您的数据连接"时,出现错误,"在 .N ...
- [EF] - Entity Framework 6处理User Defined Function(UDF SQL Server)
随着EF5的发布,新增了对数据库(SQL Server) UDF的支持,具体可以看以下的连接:https://msdn.microsoft.com/en-us/data/hh859577.aspx,新 ...
随机推荐
- Ubuntu14.04上搭建FTP服务器
Ubuntu上常用的Ftp服务器是vsFTPd.安装前检查下是否已经装好了.用 sudo service vsftpd restart,如果提示重启成功之类的信息,说明此服务器已经安装好了vsFTPd ...
- react按需加载(getComponent优美写法),并指定输出模块名称解决缓存(getComponent与chunkFilename)
react配合webpack进行按需加载的方法很简单,Route的component改为getComponent,组件用require.ensure的方式获取,并在webpack中配置chunkFil ...
- csrf
什么是CSRF: CSRF(Cross-site request forgery),中文名称:跨站请求伪造 攻击者盗用了你的身份,以你的名义发送恶意请求.CSRF能够做的事情包括:以你名义发送邮件,发 ...
- linux虚拟化概述
虚拟化硬件虚拟化:一台物理机虚拟出多台逻辑上的计算机cpu,内存可分配给多个虚拟机软件虚拟化:一个LAMP平台支撑多个网站桌面虚拟化...... 虚拟机:通过软件平台模拟出的计算机对最终用户来说,感受 ...
- 【前端】诸葛io收集前端js报错信息
转载请注明出处:http://www.cnblogs.com/shamoyuu/p/zhuge_error.html 一.什么是诸葛io 诸葛io就是通过分析用户的操作事件对用户数据,行为路径等进行分 ...
- PHPmysqli的 预处理执行插入语句
预编译在mysql端 预编译可以自动防止sql注入攻击 <?php //预编译技术 //1.创建一个mysqli对象 //2.创建myslqi预编译对象 $mysqli=); $mysqli-& ...
- 过滤Java中特殊字符
过滤Java中特殊字符 /** * @Title:FilterString.java * @Package:com.you.model * @Description:过滤Java中特殊字符 * @Au ...
- 修改MyEclipse行数的颜色
修改MyEclipse行数的颜色 1.未修改前,行数的颜色 2.依次选择"Window--->Preferences" 3.选择"General--->Edi ...
- Caused by: java.lang.ClassNotFoundException: org.hibernate.annotations.common.reflection.MetadataPro
1.错误描述 信息: MLog clients using java 1.4+ standard logging. 2014-7-12 19:29:20 com.mchange.v2.c3p0.C3P ...
- JavaScript的几种常见的创建方式
1.通过Object构造函数或者对象字面量创建单个对象 使用字面量方法创建对象:var stut = {name: "张三"}; 使用内置构造函数创建对象:var stu = ne ...