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,新 ...
随机推荐
- Win10 部署 依赖 NET3.5 项目,报错 无法安装 NET3.5 ,该如何解决?
下载 NetFx3.cab Cab 安装包 拷贝 NetFx3.cab 文件至 C:\Windows 目录 打开命令行窗口(管理员权限) 输入以下内容: dism /online /Enable-Fe ...
- window 环境变量保存位置在哪里?
注册表-regedit.exe 用户变量: HKEY_CURRENT_USER\Environment 系统变量: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSe ...
- 《android开发艺术探索》读书笔记(二)--IPC机制
接上篇<android开发艺术探索>读书笔记(一) No1: 在android中使用多进程只有一种方法,那就是给四大组件在AndroidMenifest中指定android:process ...
- Hama顶点编程
Hama是基于HDFS上的BSP模型实现. Apache Hame是Google Pregel的开源实现 Pregel是Google提出的一个面向大规模图计算的通用编程模型.许多实际应用中都涉及到大型 ...
- 2018.3.6学习java的第一天
学习java,那么不得不先了解一下java,java分为三部分,JAVA SE,JAVA EE和JAVA ME,其中前期我们首先要学习Java SE.java是一门语言,我们平时人与人之间对话,用中文 ...
- javascript-深入理解&&和||
先从两个问题看起: 第一个问题 为什么 a && b 返回的是true,b && a 返回的是6 var user = 6; var both = true; cons ...
- java发送邮件时遇到的坑
之前用163邮箱发邮件时明明是成功的,但是使用中国移动自己的邮箱时,无论如何在linux服务器中都发送不成功,一开始报如下错误: javax.mail.MessagingException: Unkn ...
- linux驱动---字符设备的注册register_chrdev说起
首先我们在注册函数里面调用了register_chrdev(MEM_MAJOR,"mem",&memory_fops),向内核注册了一个字符设备. 第一个参数是主设备号,0 ...
- JSP标签c:forEach实例
JSP标签c:forEach实例 1.实例源码 <%@ page language="java" import="java.util.*" pageEnc ...
- Linux显示2015年日历表
Linux显示2015年日历表 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ cal 2015 2015 一月 二月 三月 日 一 二 三 四 五 六 日 一 ...