使用实体框架进行全文搜索:不能对列使用CONTAINS或FREETEXT谓词,因为它不是全文索引的

时间:2014-12-02 12:11:22

标签: sql-server entity-framework full-text-search

我正在使用EF 6并尝试使用全文搜索。我在执行之前使用IDbCommandInterceptor来修改查询,因此结果查询如下所示:

...AND (CONTAINS ([UserFullName], N''Римский ''))

全文索引已经像这样创建了

 CREATE FULLTEXT INDEX 
 ON [dbo].[Documents_CreditContracts](UserFullName, FullName, Number, StoreName, UserName) 
 KEY INDEX PK_Documents_CreditContracts

并像这样执行查询:

 SELECT top 1000 *   
 FROM [MKD_OneBillionDollars2].[dbo].[Documents_CreditContracts]  
 WHERE CONTAINS(UserFullName, N'Римский ')

但是当我执行EF查询时,我收到错误:

  

不能在列' UserFullName'上使用CONTAINS或FREETEXT谓词因为它不是全文索引。

完整的EF查询:

exec sp_executesql N'SELECT TOP (10) 
    [Project5].[C1] AS [C1], 
    [Project5].[Id] AS [Id], 
    [Project5].[DocumentTypeId] AS [DocumentTypeId], 
    [Project5].[Number] AS [Number], 
    [Project5].[FullName] AS [FullName], 
    [Project5].[Amount] AS [Amount], 
    [Project5].[SignDate] AS [SignDate], 
    [Project5].[UserFullName] AS [UserFullName], 
    [Project5].[TableNumber] AS [TableNumber], 
    [Project5].[BankId] AS [BankId], 
    [Project5].[UserBankCode] AS [UserBankCode], 
    [Project5].[StoreName] AS [StoreName], 
    [Project5].[StoreCode] AS [StoreCode], 
    [Project5].[StoreBankCode] AS [StoreBankCode], 
    [Project5].[UserName] AS [UserName]
    FROM ( SELECT [Project5].[Id] AS [Id], [Project5].[DocumentTypeId] AS [DocumentTypeId], [Project5].[Number] AS [Number], [Project5].[FullName] AS [FullName], [Project5].[Amount] AS [Amount], [Project5].[SignDate] AS [SignDate], [Project5].[UserFullName] AS [UserFullName], [Project5].[TableNumber] AS [TableNumber], [Project5].[BankId] AS [BankId], [Project5].[UserBankCode] AS [UserBankCode], [Project5].[StoreName] AS [StoreName], [Project5].[StoreCode] AS [StoreCode], [Project5].[StoreBankCode] AS [StoreBankCode], [Project5].[UserName] AS [UserName], [Project5].[C1] AS [C1], row_number() OVER (ORDER BY [Project5].[Id] ASC) AS [row_number]
        FROM ( SELECT 
            [Project1].[Id] AS [Id], 
            [Project1].[DocumentTypeId] AS [DocumentTypeId], 
            [Project1].[Number] AS [Number], 
            [Project1].[FullName] AS [FullName], 
            [Project1].[Amount] AS [Amount], 
            [Project1].[SignDate] AS [SignDate], 
            [Project1].[UserFullName] AS [UserFullName], 
            [Project1].[TableNumber] AS [TableNumber], 
            [Project1].[BankId] AS [BankId], 
            [Project1].[UserBankCode] AS [UserBankCode], 
            [Project1].[StoreName] AS [StoreName], 
            [Project1].[StoreCode] AS [StoreCode], 
            [Project1].[StoreBankCode] AS [StoreBankCode], 
            [Project1].[UserName] AS [UserName], 
            [Project1].[C1] AS [C1]
            FROM ( SELECT 
                [Extent1].[Id] AS [Id], 
                [Extent1].[DocumentTypeId] AS [DocumentTypeId], 
                [Extent2].[Number] AS [Number], 
                [Extent2].[FullName] AS [FullName], 
                [Extent2].[Amount] AS [Amount], 
                [Extent2].[SignDate] AS [SignDate], 
                [Extent2].[UserFullName] AS [UserFullName], 
                [Extent2].[TableNumber] AS [TableNumber], 
                [Extent2].[BankId] AS [BankId], 
                [Extent2].[UserBankCode] AS [UserBankCode], 
                [Extent2].[StoreName] AS [StoreName], 
                [Extent2].[StoreCode] AS [StoreCode], 
                [Extent2].[StoreBankCode] AS [StoreBankCode], 
                [Extent2].[UserName] AS [UserName], 
                ''0X0X'' AS [C1]
                FROM  [dbo].[Documents] AS [Extent1]
                INNER JOIN [dbo].[Documents_CreditContracts] AS [Extent2] ON [Extent1].[Id] = [Extent2].[Id]
            )  AS [Project1]
            WHERE ( EXISTS (SELECT 
                1 AS [C1]
                FROM   (SELECT [Extent3].[RegisterId] AS [RegisterId], [Extent3].[DocumentId] AS [DocumentId], [Join2].[Id1], [Join2].[C1]
                    FROM  [dbo].[DocumentInPackage] AS [Extent3]
                    INNER JOIN  (SELECT [Extent4].[Id] AS [Id1], [Project2].[C1] AS [C1]
                        FROM  [dbo].[Registers] AS [Extent4]
                        LEFT OUTER JOIN  (SELECT 
                            [Extent5].[Id] AS [Id], 
                            cast(1 as bit) AS [C1]
                            FROM [dbo].[Registers_CreditContractRegisters] AS [Extent5] ) AS [Project2] ON [Extent4].[Id] = [Project2].[Id] ) AS [Join2] ON [Extent3].[RegisterId] = [Join2].[Id1]
                    WHERE CASE WHEN ( NOT (([Join2].[C1] = 1) AND ([Join2].[C1] IS NOT NULL))) THEN ''5X'' ELSE ''5X0X'' END LIKE ''5X0X%'' ) AS [Filter1]
                LEFT OUTER JOIN  (SELECT [Extent6].[Id] AS [Id2], [Project3].[OrpId] AS [OrpId], [Project3].[C1] AS [C1]
                    FROM  [dbo].[Registers] AS [Extent6]
                    LEFT OUTER JOIN  (SELECT 
                        [Extent7].[OrpId] AS [OrpId], 
                        [Extent7].[Id] AS [Id], 
                        cast(1 as bit) AS [C1]
                        FROM [dbo].[Registers_CreditContractRegisters] AS [Extent7] ) AS [Project3] ON [Extent6].[Id] = [Project3].[Id] ) AS [Join4] ON [Filter1].[RegisterId] = [Join4].[Id2]
                WHERE ([Project1].[Id] = [Filter1].[DocumentId]) AND ((CASE WHEN (CASE WHEN ([Join4].[Id2] IS NULL) THEN CAST(NULL AS varchar(1)) WHEN ( NOT (([Join4].[C1] = 1) AND ([Join4].[C1] IS NOT NULL))) THEN ''5X'' ELSE ''5X0X'' END LIKE ''5X0X%'') THEN CASE WHEN ([Join4].[Id2] IS NULL) THEN CAST(NULL AS int) WHEN ( NOT (([Join4].[C1] = 1) AND ([Join4].[C1] IS NOT NULL))) THEN CAST(NULL AS int) ELSE [Join4].[OrpId] END END) = @p__linq__0)
            )) AND (CONTAINS ([UserFullName], N''Римский ''))
        )  AS [Project5]
    )  AS [Project5]
    WHERE [Project5].[row_number] > 0
    ORDER BY [Project5].[Id] ASC',N'@p__linq__0 int',@p__linq__0=1

有任何想法如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

我的问题解决方法是手动编写sql查询并执行它。并将结果映射到EF实体。很多工作,是的。

答案 1 :(得分:0)

我知道答案的日期相对于提出问题时的日期,但我发现this answer有助于解决我的类似问题。

在该示例中,您使用拦截器(类型为IDbCommandInterceptor)来调整在服务器上执行之前由EF6 LINQ查询生成的SQL。这样,您仍然可以利用LINQ功能,而不必构建自己的复杂SQL查询生成器。