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,新 ...
随机推荐
- 老男孩Python全栈开发(92天全)视频教程 自学笔记14
day14课程内容: 深浅拷贝 #浅拷贝只能拷贝一层s=[1,'a','b']s1=s.copy()#浅拷贝print(s1)#[1, 'a', 'b']s[0]=2print(s1,s)#[1, ' ...
- 在JDBC中使用Java8的日期LocalDate、LocalDateTime
在实体Entity里面,可以使用java.sql.Date.java.sql.Timestamp.java.util.Date来映射到数据库的date.timestamp.datetime等字段 但是 ...
- Spark第一个应用程序
首先要对源码进行编译,生成对应hadoop版本的spark开发程序jar包,上篇已经写了具体的过程,这里不再赘述. 在安装spark的机器上,下载eclipse-java-x86_64版本,将spar ...
- R︱mlr包帮你挑选最适合数据的机器学习模型(分类、回归)+机器学习python和R互查手册
一.R语言的mlr packages install.packages("mlr")之后就可以看到R里面有哪些机器学习算法.在哪个包里面. a<-listLearners() ...
- Hybrid APP 架构设计思路
关于Hybrid模式开发app的好处,网络上已有很多文章阐述了,这里不展开. 本文将从以下几个方面阐述Hybrid app架构设计的一些经验和思考. 原文及讨论请到 github issue 通讯 作 ...
- PHP学习笔记-POST
$_POST 描述通过http POST方式提交的数据都会封装到$_POST数组中 有些数据的提交必须使用post 比如上传文件 Post get提交 的区别 安全性 数据传输大小 浏览器限制文本大小 ...
- free 或delete后指针怎么样了
free()和delete()只是把指针所指向的内存释放掉,但是并没有把指针本身删除,也没有把指针置为NULL; #include<iostream> using namespace st ...
- Linux显示以时间降序显示文件
Linux显示以时间降序显示文件 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ ls -lrt 总用量 56 -rw-r--r-- 1 youhaidong ...
- asp.net URL重新实例
void Application_Start(object sender, EventArgs e) { // 在应用程序启动时运行的代码 RegisterRoutes(); } // 页面存放目录 ...
- httpclient案例一(调用识别接口)
public Map<String, Object> pictureRecognition(String recotype, MultipartFile imageFile) { Stri ...