# 六、空间数据类型

## 概述

SQL Server 2008 引入了两种空间数据类型。这些提供了以更自然的方式编写面向地理的查询的能力，因为服务器知道坐标、距离等等。这些类型是:

*   [几何](http://technet.microsoft.com/en-us/library/cc280487.aspx):欧几里德(平面空间)标准运算，由开放地理空间联盟(OGC)定义。
*   [地理](http://technet.microsoft.com/en-us/library/cc280766.aspx):环地作战，同样由 OGC 定义。

他们提供类似的操作，包括:

*   计算两点之间的距离。
*   检查点是否包含在多边形中。
*   获取两个多边形的交集。

空间类型不是 SQL Server 的专属类型，但并非所有实体框架提供程序都支持它们；有关更多信息，请查看实体框架提供者对空间类型的支持:[http://msdn.microsoft.com/en-us/data/dn194325.aspx](http://msdn.microsoft.com/en-us/data/dn194325.aspx)。

实体框架处理空间类型就像处理所有其他类型一样。也就是说，它可以从包含空间类型属性的实体生成数据库，并使用 LINQ 查询这些类型。他们的。NET 对应的是 [DbGeography](http://msdn.microsoft.com/en-us/library/system.data.spatial.dbgeography.aspx) 和[DbGeography](http://msdn.microsoft.com/en-us/library/system.data.spatial.dbgeometry.aspx)。

对这些类型的详细解释超出了本章的范围，所以我只留下一些查询示例。

首先，让我们从一个具有地理属性的类开始。

```cs
public class Venue
{
  public Int32 VenueId { get; set; }

  public String Name { get; set; }

  public DbGeography Location { get; set; } 
}

```

作为开胃菜，下面是两个简单的查询，用于计算固定位置点和一些场地之间的距离，以及使用 LINQ 检查落在一个区域内的点。

```cs
//a fixed location in Well-known Text (WKT) format
var location = DbGeography.FromText(string.Format("POINT({0} {1})", 41, 8));

//an area in WKT and Spatial Reference System Identifier (SRID) 4326
var area = DbGeography.MultiPointFromText("MULTIPOINT(53.095124 -0.864716, 53.021255 -1.337128, 52.808019 -1.345367, 52.86153 -1.018524)", 4326);

//the distance from all stored locations to the fixed location
var venuesAndDistanceToLocation = ctx.Venues
.OrderBy(v = v.Location.Distance(location))
.Select(v => new { Venue = v, Distance = v.Location.Distance(location) }).ToList();

//venues inside the area
var pointInsideArea = ctx.Venues.Where(x => area.Intersects(x.Location)).ToList();

```