Entity Framework 代码优先、FullTextIndex 和继承

Entity Framework Code First, FullTextIndex & Inheritance

我目前正在和我的团队一起处理一个项目,我们有一个包含大量数据的大型 SQL Server 2014 数据库。为了提高性能,我们选择按照 tutorial 将 FullTextIndex 与 EntityFramework 一起使用。由于继承,我们现在遇到 table Customer 的问题(我们认为是这样,可能是其他原因)。这是模型(简化):

public abstract class Person // In db : dbo.People
{
    public int Id { get; set }
    public string LastName { get; set; }
    // Other properties
}

public class Customer : Person // In db : dbo.People_Customer
{
    // Inherited properties from Person
}

public class Mission // In db : dbo.Missions
{
    public int CustomerIdPerson { get; set; }
    public virtual Customer Customer { get; set; }
}

当我尝试通过以下查询通过客户搜索任务时:

context.Missions.Where(m => m.Customer.LastName.Contains("foo")).ToList();

我有这个错误(由 SQL 服务器引发):Cannot use a CONTAINS or FREETEXT predicate on column 'LastName' because it is not full-text indexed.

这里是EF生成的SQL(我只是用SQL参数的实际值替换了变量)。

SELECT 
[Limit3].[IdJourney] AS [IdJourney]
FROM ( SELECT TOP (2000) 
    [Project4].[IdJourney] AS [IdJourney]
    FROM    (SELECT 
        [Project2].[IdJourney] AS [IdJourney], 
        [Project2].[SuppressionDate] AS [SuppressionDate], 
        [Project2].[State] AS [State], 
        [Project2].[TripIdTrip] AS [TripIdTrip], 
        [Project2].[IdTrip] AS [IdTrip], 
        [Project2].[SuppressionDate1] AS [SuppressionDate1], 
        [Project2].[TripSetIdTripSet] AS [TripSetIdTripSet], 
        [Project2].[C1] AS [C1], 
        (SELECT TOP (1) 
            [Extent6].[PlannedDate] AS [PlannedDate]
            FROM  [dbo].[PlannedElements_PlannedBusinessFleetElement] AS [Extent5]
            INNER JOIN [dbo].[PlannedElements] AS [Extent6] ON [Extent5].[IdPlannedElement] = [Extent6].[IdPlannedElement]
            WHERE (0 = [Extent5].[TypeOfBusinessFleetElement]) AND ([Project2].[IdJourney] = [Extent5].[JourneyIdJourney])) AS [C2]
        FROM ( SELECT 
            [Extent1].[IdJourney] AS [IdJourney], 
            [Extent1].[SuppressionDate] AS [SuppressionDate], 
            [Extent1].[State] AS [State], 
            [Extent1].[TripIdTrip] AS [TripIdTrip], 
            [Extent2].[IdTrip] AS [IdTrip], 
            [Extent2].[SuppressionDate] AS [SuppressionDate1], 
            [Extent2].[TripSetIdTripSet] AS [TripSetIdTripSet], 
            (SELECT TOP (1) 
                [Extent4].[PlannedDate] AS [PlannedDate]
                FROM  [dbo].[PlannedElements_PlannedBusinessFleetElement] AS [Extent3]
                INNER JOIN [dbo].[PlannedElements] AS [Extent4] ON [Extent3].[IdPlannedElement] = [Extent4].[IdPlannedElement]
                WHERE (0 = [Extent3].[TypeOfBusinessFleetElement]) AND ([Extent1].[IdJourney] = [Extent3].[JourneyIdJourney])) AS [C1]
            FROM  [dbo].[Journeys] AS [Extent1]
            INNER JOIN [dbo].[Trips] AS [Extent2] ON [Extent1].[TripIdTrip] = [Extent2].[IdTrip]
        )  AS [Project2] ) AS [Project4]
    LEFT OUTER JOIN [dbo].[TripSets] AS [Extent7] ON [Project4].[TripSetIdTripSet] = [Extent7].[IdTripSet]
    LEFT OUTER JOIN  (SELECT [Extent8].[IdPerson] AS [IdPerson1], [Extent8].[LastName] AS [LastName]
        FROM  [dbo].[Persons] AS [Extent8]
        INNER JOIN [dbo].[Persons_Customer] AS [Extent9] ON [Extent8].[IdPerson] = [Extent9].[IdPerson] ) AS [Join5] ON [Extent7].[CustomerIdPerson] = [Join5].[IdPerson1]
    WHERE (CONTAINS([Join5].[LastName], '"foo*"'))
)  AS [Limit3]

我确定该列已建立全文索引。我已经多次重建目录和索引。对于其他未继承的 table,FullTextSearch 工作正常...

我没有主意了...感谢您的帮助。 :)

问题可能与以下事实有关:CONTAINS 可以访问 Join 而不是 table,因此 SQL 服务器不喜欢它。我通常避免继承写在数据库上的 classes(害怕 EF 行为 :))。

无论如何你可以避免在
的片段中添加 [myAlias] CONTAINS([myAlias].[LastName], '"foo*"')
询问。可能有时您需要插入 [myAlias] 以便您可以更改 FtsInterceptor class 中的代码。您可以再添加 1 个 "tag"
private const string FullTextPrefixWithoutAlias = "-FTSPREFIXNOALIAS-";
然后调用不同的 RewriteFullTextQuery 如果您指定 FTSPREFIXNOALIAS(或者更好地向 RewriteFullTextQuery 添加参数以指定行为)。 RewriteFullTextQuery 的唯一区别是,如果您不想要您需要使用的别名
string.Format(@"contains([], @{0})",parameter.ParameterName));
而不是
string.Format(@"contains([].[], @{0})",parameter.ParameterName));

以同样的方式,您还可以向 FtsInterceptor 添加更多控制,添加更多 "tags"...