Linq到SQL和SQL地理类型
本文关键字:SQL 类型 Linq | 更新日期: 2023-09-27 18:21:49
是否有任何方法可以在Visual Studio 2012中使用LINQ to SQL映射到SQL地理类型?我需要能够将SQL地理类型插入数据库中,并查询SQL地理类型。我已经提到了这个链接,但它似乎没有解决我的问题。
LINQ to SQL本机不支持您已经讨论过的SQL地理类型。要解决此问题,请结合使用数据库中的视图、存储过程和计算列。简而言之:
- 在将地理数据类型转换为varbinary的表中包含或添加计算列。LINQ to SQL可以将此计算列映射到字节数组
- 为每个将具有地理数据的表创建视图,但不包含不支持的地理数据类型列
- 使用LINQ to SQL查询中的视图,而不是原始表
- 要插入或更新地理数据,请使用存储过程或原始SQL查询来执行这些操作
以下是步骤的说明(未经测试!):
创建表格:例如
CREATE TABLE Locations (
Id INT IDENTITY(1,1) PRIMARY KEY,
Name NVARCHAR(50) NOT NULL,
Location GEOGRAPHY NOT NULL,
LocationVarbinary AS CAST(Location AS VARBINARY(MAX))
)
注:如果您想要的表已经存在,请使用本机SQL添加地理位置和计算列。
基于所需的表创建视图,但不包括不支持的地理数据类型列:例如
CREATE VIEW LocationsView AS
SELECT Id, Name, Location.Lat AS Latitude, Location.Long AS Longitude
FROM Locations
在LINQ to SQL查询中使用这些视图,而不是表:例如
var db = new MyDataContext();
var locations = from l in db.LocationsView
select l;
要插入或更新地理数据,请使用存储过程或原始SQL查询来执行插入或更新。例如
CREATE PROCEDURE InsertLocation
@Name NVARCHAR(50),
@Latitude FLOAT,
@Longitude FLOAT
AS
BEGIN
DECLARE @Location GEOGRAPHY = geography::Point(@Latitude, @Longitude, 4326)
INSERT INTO Locations (Name, Location)
VALUES (@Name, @Location)
END
从C#代码调用存储过程:例如
var db = new MyDataContext();
db.InsertLocation("New Location", 47.65100, -122.34900);
要使用地理数据(例如获取距离内的位置),请结合使用SQL Server地理数据类型中的SqlFunctions类和STDistance方法。例如
var db = new MyDataContext();
var point = DbGeography.FromText("POINT(-122.34900 47.65100)");
var distance = 1000; // meters
var locations = from l in db.LocationsView
where SqlFunctions.DataLength(l.LocationVarbinary) > 0
let location = DbGeography.FromBinary(l.LocationVarbinary)
where location.Distance(point) <= distance
select l;
此查询应返回LocationsView中位置列位于指定点 1000米范围内的所有行
注:DbGeography.FromBinary
无法处理NULL值,因此SqlFunctions.DataLength(l.LocationVarbinary) > 0
筛选出长度为0的LocationVarbinary行(即计算出的源Location列为NULL的行)。