如何用C#及Entity Framework将GeoJSON转换导入SQL Server Geography字段?
解决方法:将澳大利亚各州GeoJSON导入SQL Server 2012 Geography字段
由于SQL Server 2012没有内置的GeoJSON转Geography函数,且部分Contrib库对旧版本支持有限,我们可以通过GeoJson.Net解析+WKT转换的方式实现,步骤如下:
1. 准备依赖包
通过NuGet安装以下包:
GeoJson.Net:核心的GeoJSON解析库GeoJSON.Net.Contrib.Wkt:将GeoJSON几何体转换为WKT格式(SQL Server原生支持的格式)System.Data.Entity:提供DbGeography类型支持
2. 读取并解析GeoJSON文件
先把本地的GeoJSON文件读取为字符串,再反序列化为FeatureCollection(你的数据是多个州的区域,对应GeoJSON的Feature集合):
using System.IO; using GeoJSON.Net.Feature; using Newtonsoft.Json; // 读取GeoJSON文件内容 string geoJsonPath = @"C:\your-path\australia-states.geojson"; string geoJsonContent = File.ReadAllText(geoJsonPath); // 反序列化为FeatureCollection var featureCollection = JsonConvert.DeserializeObject<FeatureCollection>(geoJsonContent);
3. 转换GeoJSON几何体为DbGeography
遍历每个Feature,将其几何体转换为WKT格式,再通过DbGeography.FromText生成SQL Server兼容的Geography对象:
using GeoJSON.Net.Contrib.Wkt; using System.Data.Spatial; foreach (var feature in featureCollection.Features) { // 将GeoJSON几何体转为WKT字符串 string wktGeometry = feature.Geometry.ToWkt(); // 生成DbGeography对象(4326是WGS84坐标系的EPSG代码,必须指定) DbGeography stateBoundary = DbGeography.FromText(wktGeometry, 4326); // 获取州名(假设GeoJSON的Properties里有"name"字段,可根据你的实际字段调整) string stateName = feature.Properties["name"].ToString(); // 下一步:插入到数据库 }
4. 插入到SQL Server数据库
这里用ADO.NET实现插入(兼容性更好,适配SQL Server 2012):
先创建数据库表
CREATE TABLE AustralianStates ( Id INT IDENTITY(1,1) PRIMARY KEY, StateName NVARCHAR(100) NOT NULL, StateBoundary GEOGRAPHY NOT NULL );
执行插入操作
using System.Data.SqlClient; // 替换为你的数据库连接字符串 string connectionString = "Data Source=your-server;Initial Catalog=your-db;Integrated Security=True;"; using (SqlConnection conn = new SqlConnection(connectionString)) { conn.Open(); foreach (var feature in featureCollection.Features) { string wktGeometry = feature.Geometry.ToWkt(); DbGeography stateBoundary = DbGeography.FromText(wktGeometry, 4326); string stateName = feature.Properties["name"].ToString(); // 构造插入命令 string insertSql = @"INSERT INTO AustralianStates (StateName, StateBoundary) VALUES (@StateName, @StateBoundary)"; using (SqlCommand cmd = new SqlCommand(insertSql, conn)) { cmd.Parameters.AddWithValue("@StateName", stateName); cmd.Parameters.AddWithValue("@StateBoundary", stateBoundary); // 执行插入 cmd.ExecuteNonQuery(); } } }
5. 初步测试:保存整个GeoJSON为单个Geography字段
如果你只想先测试把整个GeoJSON存入单个字段,可以将所有Feature的几何体合并为GeometryCollection,再转换插入:
using GeoJSON.Net.Geometry; // 合并所有Feature的几何体为GeometryCollection var allGeometries = featureCollection.Features.Select(f => f.Geometry).ToList(); var geometryCollection = new GeometryCollection(allGeometries); // 转换为DbGeography string collectionWkt = geometryCollection.ToWkt(); DbGeography entireAustralia = DbGeography.FromText(collectionWkt, 4326); // 插入到数据库(可新建表或字段) using (SqlConnection conn = new SqlConnection(connectionString)) { conn.Open(); string insertSql = "INSERT INTO AustraliaRegions (EntireBoundary) VALUES (@Boundary)"; using (SqlCommand cmd = new SqlCommand(insertSql, conn)) { cmd.Parameters.AddWithValue("@Boundary", entireAustralia); cmd.ExecuteNonQuery(); } }
关键注意事项
- 坐标系必须是WGS84(EPSG:4326):SQL Server的Geography类型仅支持这个坐标系,如果你的GeoJSON用了其他坐标系,需要先转换(可借助GDAL等工具预处理)。
- 几何体必须闭合:Polygon类型的GeoJSON必须保证最后一个点和第一个点坐标相同,否则SQL Server会报错。
- 避免超大几何体:SQL Server 2012的Geography字段有大小限制,如果单个州的边界太复杂,可能需要简化几何体后再插入。
内容的提问来源于stack exchange,提问作者tone
相关产品推荐
相关产品推荐

