繁体   English   中英

如何从 EF Core 的 FromSqlRaw 获取空间值

[英]How do I get a spatial value from EF Core's FromSqlRaw

最近我遇到了一个问题,我只需要使用 FromSqlRaw 到我的数据库来执行 Postgresql 扩展之一的功能。 此函数返回一个条目,我想以某种方式获取此条目的值。 但是,由于某些原因,我不能这样做:

var buffer = DataContext.LayerDatas.FromSqlRaw($"select ST_Buffer(ld.\"Geom\", 100, 'join=mitre') " +
            $"from public.\"Layers\" ld where ld.\"LId\" = {layerId} and ld.\"OId\" = {objectId}").FirstOrDefault();

从 SqlRaw 获取计算值以便在我的代码中使用它的正确方法是什么?

编辑:当我通过 DBeaver 执行查询时,它给了我以下信息: 查询结果

我想在我的 C# 代码中得到这个。

但是 c# app 中的代码给了我以下异常:

42601 syntax error (at or near "d"), 

它将我的查询显示为:

{select ld."Geom", ST_Buffer(ld."Geom", 100, 'join=mitre') from public."Layers" ld where ld."LId" = f21e400c-9e6d-4c28-b14c-1f0ced5b6ebb and ld."OId" = 3126}

您使用字符串插值来生成导致无效查询的查询字符串。

... where ld."LId" = f21e400c-9e6d-4c28-b14c-1f0ced5b6ebb 

代码创建了一个 SQL 字符串,其中包含导致无效查询的注入值,而不是参数化查询。

FromSqlRaw适用于普通字符串和明确指定的参数。 事实上,文档对此有一个很大的警告

在 FromSqlRaw 中使用参数

要使用FromSqlRaw不得使用插值。 可以按位置传递参数:

var sql="select ST_Buffer(ld.Geom, 100, 'join=mitre') 
from public.Layers ld 
where ld.LId = {0} and ld.OId = {1}";

var buffer = DataContext.LayerDatas.FromSqlInterpolated(sql,layerId,objectId)
                        .FirstOrDefault();

C# 允许多行字符串,因此无需使用串联来使查询可读。

对 FromSqlInterpolated 使用插值

如果要使用插值来传递参数,则需要FromSqlInterpolated

var buffer = DataContext.LayerDatas.FromSqlInterpolated(
$"select ST_Buffer(ld.Geom, 100, 'join=mitre') 
from public.Layers ld 
where ld.LId = {layerId} and ld.OId = {objectId}"
).FirstOrDefault();

请注意,该字符串是一个没有连接的长字符串 这将产生FormattableString由预期类FromSqlInterpolated

读取 GIS 类型

ST_Buffer 是PostgreSQLMySQL使用的标准 GIS 函数,它返回空间类型。 在 SQL Server 中,它是STBuffer

EF Core通过NetTopologySuite包和文档中提到的特定于数据库的包支持空间类型。

对于 PostgreSQL,正确的包是Npgsql.EntityFrameworkCore.PostgreSQL.NetTopologySuite 它的使用在使用 NetTopologySuite 的空间映射中进行了解释

要与 EF Core 一起使用,安装正确的包后,需要在配置 DbContext 时注册它,例如:

options.UseSqlServer(
    @"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=WideWorldImporters",
    x => x.UseNetTopologySuite());

之后,空间类型和属性可以像其他类型一样使用:

// Find the nearest city
var nearestCity = db.Cities
    .OrderBy(c => c.Location.Distance(currentLocation))
    .FirstOrDefault();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM