我正在尝试使用SQL运算符CONTAINSTABLE
来获取搜索结果列表,如下所示:
SELECT c.*, ccontains.[RANK]
FROM Customers c
INNER JOIN CONTAINSTABLE(Customers, LastName, @searchTerm) ccontains ON c.Id = ccontains.[KEY]
并从EF Core 2.1调用此函数:
var query = DbContext.Customers.FromSql("SELECT * FROM udfSearchCustomers(@searchTerm)",
new SqlParameter(@searchTerm, mySearchTerm));
query = query.Include(c => c.Addresses).Take(maxResults);
我想对搜索结果按RANK
降序排列,以使最相关的结果排在顶部。不允许在函数中添加ORDER BY ccontains.[RANK]
,因为我的SELECT * FROM udfSearchCustomers(...)
将被EF Core包装:内部查询中不允许ORDER BY
。由于query.OrderBy(c => c.Rank)
不在RANK
实体上,因此无法添加Customer
。
我尝试使用System.Linq.Dynamic
以及其他反射解决方案来做到这一点:
query = query.OrderBy("Rank");
但是我有一个例外:
“排名”不是“客户”类型的成员
是真的。有什么方法可以对不在实体上的列进行排序,还是需要创建一个MyCustomerSearchQuery
查询对象并使用AutoMapper将其转换为Customer
?我宁愿不这样做,因为Customer
具有许多属性,并且保持同步很麻烦。
谢谢!
答案 0 :(得分:0)
您可以尝试
query = query.OrderBy(x => x.Rank);
OR
query = query.OrderBy(x => x["Rank"]);
答案 1 :(得分:0)
您可以创建带有两个参数的查询存储过程:@ searchKey,@ orderByColumn。
CREATE PROCEDURE [dbo].[UdfSearchCustomers]
@searchTerm varchar(50),
@orderByColumn varchar(50)
AS
BEGIN
DECLARE @sql NVARCHAR(MAX);
SET @sql =' SELECT c.*, ccontains.[RANK]
FROM Customers c
INNER JOIN CONTAINSTABLE(Customers, LastName, ''@searchTerm'') ccontains
ON c.Id = ccontains.[KEY]
ORDER BY @orderByColumn'
SET @sql = REPLACE(@sql, '@orderByColumn', @orderByColumn)
SET @sql = REPLACE(@sql, '@searchTerm', @searchTerm)
exec sp_executesql @sql
END
GO
然后,您可以查询与以下相同的存储过程:
var query = DbContext.Customers.FromSql("exec UdfSearchCustomers @p0, @p1", mySearchTerm, "Rank");
如果要将联接添加到地址表,则可以将联接添加到存储过程。这可能会给您您想要的结果。