C# 使用EFCore在MSSQL varchar字段中搜索多个单词
我的项目使用ASP.NETCore1.1、EFCore和SQLServer数据库 我有一个字符串数组,应该在文本字段中搜索,实际上字段是一个标签列表,数组是一个标签数组 完整场景: 在我的服务器端.Net内核上,我有一个标记数组{'tag2','tag4'} 每个位置都存储在SQL Server中,标记列表以“tag1、tag2、tag3”分隔 我想得到20个最近的地方,至少匹配一个标签 我曾考虑过将datatable作为参数传递给具有自定义类型参数的SQL函数,但是直到v2,datatable类型才包含在.Net核心中 实体DbContext类中的C代码类似于:C# 使用EFCore在MSSQL varchar字段中搜索多个单词,c#,sql-server,asp.net-core,entity-framework-core,C#,Sql Server,Asp.net Core,Entity Framework Core,我的项目使用ASP.NETCore1.1、EFCore和SQLServer数据库 我有一个字符串数组,应该在文本字段中搜索,实际上字段是一个标签列表,数组是一个标签数组 完整场景: 在我的服务器端.Net内核上,我有一个标记数组{'tag2','tag4'} 每个位置都存储在SQL Server中,标记列表以“tag1、tag2、tag3”分隔 我想得到20个最近的地方,至少匹配一个标签 我曾考虑过将datatable作为参数传递给具有自定义类型参数的SQL函数,但是直到v2,datatable
decimal lat=2.0, lng=3.0; float maxRadius=50000;
var tags = new Array<string>(){"tag1", "tag2"};
var places = await this.Set<Place>()
.FromSql("SELECT * FROM GetPlaces(@p0, @p1, @p2, @p3, @p4)", maxResults, lat, lng, maxRadius, tags).ToListAsync();
使用SQL函数,该函数将是:
CREATE FUNCTION [dbo].[GetClosestPlaces]
(@lat decimal,@lng decimal,@maxRadius float=50000)
RETURNS TABLE AS RETURN
SELECT * FROM Places
WHERE ([geography]::Point(@lat,@lng,(4326)))
.STDistance(([geography]::Point([Latitude],[Longitude],(4326))))
< @maxDistance
有什么建议吗
目标是在SQL方面减少资源消耗,在这两方面,减少时间消耗的服务应该提供非常快速的答案,因为它可能会被调用多次相同的查询
目前,我还没有在数据库中找到任何好的解决方案。因此,我使用其他过滤器距离预过滤数据库数据,然后在内存中应用文本过滤器。
它的效率要高得多:SQL解决方案为500毫秒,而linq解决方案为100-150毫秒。在这种情况下可以使用“SQL Server全文索引”吗?我想可以,但我从未使用过:它是受DTU限制的Azure DB。“标记”最多为varchar20,标记字段为varchar255您可以在SQL Azure中跨多个字段启用全文搜索。但是,您不能直接在EF中查询索引。但是,您可以很容易地使用全文索引执行自定义查询字符串。是否可以对包含的单词进行参数化?例如:在CONTAINSTags、@prm1+'或'+@prm2'中,这种语法看起来很奇怪-不是很干净。。。我找到的唯一解决方案是添加几个带有1个参数的“contains”约束。
var places = await (from p in this.Set<Place>()
.FromSql("SELECT * FROM GetClosestPlaces(@p0, @p1, @p2)", lat, lng, maxRadius)
where (from t in tags where p.Tags.Contains(t) select t).Any()
select p).Take(maxResults).ToListAsync();
CREATE FUNCTION [dbo].[GetClosestPlaces]
(@lat decimal,@lng decimal,@maxRadius float=50000)
RETURNS TABLE AS RETURN
SELECT * FROM Places
WHERE ([geography]::Point(@lat,@lng,(4326)))
.STDistance(([geography]::Point([Latitude],[Longitude],(4326))))
< @maxDistance