[英]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 是PostgreSQL和MySQL使用的标准 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.