Linq2Sql或EF4中的空间数据类型支持

20

有人知道(最好有参考资料),VS2010版本的LinqToSQL或EntityFramework v4是否支持针对SQL 2008空间数据类型的查询吗?

3个回答

24

这是一个绕过的方法,用于在Entity Framework / LINQ to Entities中实现功能:

你可以使用数据库视图来返回Well-Known-Text(在查询中使用“geometry.ToString()”)或二进制。然后一旦返回结果行,只需在.NET中将字符串/二进制转换为SqlGeometry对象即可。

以下是用于构建视图的示例查询,将几何类型的“Location”字段转换为Well-Known-Text字符串:

SELECT ID, Name, Location.ToString() as Location FROM MyTable

以下是一个示例,演示如何查询具有包含“地理”对象的Well-Known-Text或字符串表示形式的“位置”字段的结果实体:

var e = new MyApp.Data.MyDataEntities(connectionString);
var items = from i in e.MyTables
            select i;

foreach (var i in items)
{
    // "Location" is the geography field
    var l = SqlGeography.Parse(i.Location);
    var lat = l.Lat;
    var lng = l.Long;
}

另外需要注意的是,你需要在存储过程中执行任何基于空间的查询,因为你不想将整个表的数据都拉到.NET中,然后使用LINQ进行自己的空间查询。

这虽然不是原生支持SQL Spatial Types的优雅解决方法,但它能让你同时使用Entity Framework和SQL Spatial。


这是我一直在使用 L2S 进行尝试和实践的东西。 - Pure.Krome
8
我们将这些内容存储为Lat/Lng浮点列,并使用触发器创建地理信息列值。这使我们可以两全其美——既能够简单方便地获取/设置类型,又能够在存储过程中进行空间查询。 - Peter Wone

11
在EF 4.0中,您可能能够使用自定义函数的组合并假装空间类型实际上是二进制类型来拼凑出一些东西。这是我想要尝试并添加到我的提示系列中的内容。但是到目前为止,即使是这种黑客方式也没有得到证明。 :(
至于直接支持,不幸的是,无论是L2S还是EF v4都不会在VS2010时间范围内支持空间类型。 Alex James Entity Framework程序经理。

谢谢Alex,看起来是一个可靠和权威的答案!EF4为什么不支持它们(太难,需求不足,优先级太低……)有没有什么特殊的原因? - Colin Desmond
2
我不会说这是低优先级的事情。我认为这是一个高优先级的任务。但是我要说,相比我们最终做的一些事情,比如POCO、FKs、Model First等,它并不是那么高的优先级。 - Alex James
2
EF何时会支持空间类型?VS'2012后还要再等4年才能与SQL Server一起使用吗? - Chris Pietschmann
作为一则注释,EF 5支持空间数据类型。不过我不确定这是否适用于MySQL或其他数据库提供程序。 - runxc1 Bret Ferrier

1

你也可以使用手写的表和列来进行 Linq-to-SQL,并直接获取 SQL 空间类型。我在一个样本数据库上测试了以下内容(不要忘记包含对 System.SqlServer.Types 的引用和“using”)。

...

string connectionString = @"Data Source=YADDAYADDA;Initial Catalog=MUMBLEMUMBLE;Integrated Security=True";
var pointsFileDc = new PointsFileDC(connectionString);
var geos = (from point in pointsFileDc.pointsData
            select point).Take(10);
foreach (var geo in geos)
{
    ObjectDumper.Write(geo);
}

...

public class PointsFileDC : DataContext
{
    public Table<GeoPoints> pointsData;
    public PointsFileDC(string connection)
        : base(connection)
    {
    }
}

[Table(Name = "Points")]
public class GeoPoints
{
    [Column(IsPrimaryKey = true)]
    public int PointId;
    [Column]
    public SqlGeography GeoPoint;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接