3

我正在尝试使用 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");

但我有一个例外:

“Rank”不是“Customer”类型的成员

这是真的。有没有办法对不在实体上的列进行排序,或者我需要创建一个MyCustomerSearchQuery查询对象并使用 AutoMapper 将它们转换为Customer?我宁愿不这样做,因为Customer有许多属性并且保持它们同步会很麻烦。

提前致谢!

4

2 回答 2

0

你可以试试

 query = query.OrderBy(x => x.Rank);

或者

 query = query.OrderBy(x => x["Rank"]);
于 2019-11-01T09:39:38.880 回答
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");

如果要将连接添加到地址表,则可以将连接添加到存储过程。这可能会给您想要的结果。

于 2019-11-01T12:07:29.813 回答