Entity framework 中复杂查询的全文索引搜索
Full text index search for complex query in Entity framework
我正在尝试使用 EF 6.0 执行全文索引搜索。我正在使用 IDbCommandInterceptor (http://www.entityframework.info/Home/FullTextSearch) 执行全文搜索,但它抛出了这个异常:
Cannot use a CONTAINS or FREETEXT predicate on column 'FirstName'
because it is not full-text indexed.
Linq 查询:
ListOfEmployees = _context.EmployeeCvs.Include(x => x.Employee)
.Include(x => x.Tags)
.Include(x => x.ProjectExperiences)
.Where(x => x.Employee.FirstName.Contains(SearchQuery.Keyword) || x.Employee.LastName.Contains(SearchQuery.Keyword) || x.ProjectExperiences.Any(y => y.ProjectTitle.Contains(SearchQuery.Keyword) || y.Description.Contains(SearchQuery.Keyword)) || x.Tags.Any(t => t.Title.Contains(SearchQuery.Keyword)))
.ToList();
下面是 EF 执行的查询:
exec sp_executesql N'SELECT
[UnionAll1].[Id] AS [C1],
[UnionAll1].[Id1] AS [C2],
[UnionAll1].[Id2] AS [C3],
[UnionAll1].[Id3] AS [C4],
[UnionAll1].[Id4] AS [C5],
[UnionAll1].[Id5] AS [C6],
[UnionAll1].[Id6] AS [C7],
[UnionAll1].[Id7] AS [C8],
[UnionAll1].[Id8] AS [C9],
[UnionAll1].[FirstName] AS [C10],
[UnionAll1].[LastName] AS [C11],
[UnionAll1].[EnterpriseId] AS [C12],
[UnionAll1].[Level] AS [C13],
[UnionAll1].[C1] AS [C14],
[UnionAll1].[Id9] AS [C15],
[UnionAll1].[Id10] AS [C16],
[UnionAll1].[Title] AS [C17],
[UnionAll1].[CreatedDate] AS [C18],
[UnionAll1].[CreatedBy] AS [C19],
[UnionAll1].[UpdatedDate] AS [C20],
[UnionAll1].[UpdatedBy] AS [C21],
[UnionAll1].[IsDeleted] AS [C22],
[UnionAll1].[TagType_Id] AS [C23],
[UnionAll1].[ProjectExperience_Id] AS [C24],
[UnionAll1].[C2] AS [C25],
[UnionAll1].[C3] AS [C26],
[UnionAll1].[C4] AS [C27],
[UnionAll1].[C5] AS [C28],
[UnionAll1].[C6] AS [C29],
[UnionAll1].[C7] AS [C30],
[UnionAll1].[C8] AS [C31],
[UnionAll1].[C9] AS [C32],
[UnionAll1].[C10] AS [C33],
[UnionAll1].[C11] AS [C34],
[UnionAll1].[C12] AS [C35],
[UnionAll1].[C13] AS [C36],
[UnionAll1].[C14] AS [C37],
[UnionAll1].[C15] AS [C38],
[UnionAll1].[C16] AS [C39],
[UnionAll1].[C17] AS [C40]
FROM (SELECT
CASE WHEN ([Join7].[FKEmployeeCvId] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1],
[Extent1].[Id] AS [Id],
[Extent2].[Id] AS [Id1],
[Extent3].[Id] AS [Id2],
[Extent4].[Id] AS [Id3],
[Extent5].[Id] AS [Id4],
[Extent6].[Id] AS [Id5],
[Extent7].[Id] AS [Id6],
[Extent1].[Id] AS [Id7],
[Extent1].[Id] AS [Id8],
[Extent4].[FirstName] AS [FirstName],
[Extent5].[LastName] AS [LastName],
[Extent6].[EnterpriseId] AS [EnterpriseId],
[Extent7].[Level] AS [Level],
[Join7].[Id] AS [Id9],
[Join7].[Id] AS [Id10],
[Join7].[Title] AS [Title],
[Join7].[CreatedDate] AS [CreatedDate],
[Join7].[CreatedBy] AS [CreatedBy],
[Join7].[UpdatedDate] AS [UpdatedDate],
[Join7].[UpdatedBy] AS [UpdatedBy],
[Join7].[IsDeleted] AS [IsDeleted],
[Join7].[TagType_Id] AS [TagType_Id],
[Join7].[ProjectExperience_Id] AS [ProjectExperience_Id],
CAST(NULL AS int) AS [C2],
CAST(NULL AS varchar(1)) AS [C3],
CAST(NULL AS int) AS [C4],
CAST(NULL AS varchar(1)) AS [C5],
CAST(NULL AS varchar(1)) AS [C6],
CAST(NULL AS datetime2) AS [C7],
CAST(NULL AS varchar(1)) AS [C8],
CAST(NULL AS datetime2) AS [C9],
CAST(NULL AS varchar(1)) AS [C10],
CAST(NULL AS bit) AS [C11],
CAST(NULL AS int) AS [C12],
CAST(NULL AS int) AS [C13],
CAST(NULL AS int) AS [C14],
CAST(NULL AS int) AS [C15],
CAST(NULL AS int) AS [C16],
CAST(NULL AS int) AS [C17]
FROM (SELECT [Var_41].[Id] AS [Id], [Var_41].[Employee_Id] AS [Employee_Id]
FROM [dbo].[EmployeeCv] AS [Var_41]
WHERE ([Var_41].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent1]
LEFT OUTER JOIN (SELECT [Var_42].[Id] AS [Id], [Var_42].[FirstName] AS [FirstName], [Var_42].[Discriminator] AS [Discriminator]
FROM [dbo].[Employee] AS [Var_42]
WHERE ([Var_42].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent2] ON ([Extent2].[Discriminator] = N''Employee'') AND ([Extent1].[Employee_Id] = [Extent2].[Id])
LEFT OUTER JOIN (SELECT [Var_43].[Id] AS [Id], [Var_43].[LastName] AS [LastName], [Var_43].[Discriminator] AS [Discriminator]
FROM [dbo].[Employee] AS [Var_43]
WHERE ([Var_43].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent3] ON ([Extent3].[Discriminator] = N''Employee'') AND ([Extent1].[Employee_Id] = [Extent3].[Id])
LEFT OUTER JOIN (SELECT [Var_44].[Id] AS [Id], [Var_44].[FirstName] AS [FirstName], [Var_44].[Discriminator] AS [Discriminator]
FROM [dbo].[Employee] AS [Var_44]
WHERE ([Var_44].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent4] ON ([Extent4].[Discriminator] = N''Employee'') AND ([Extent1].[Employee_Id] = [Extent4].[Id])
LEFT OUTER JOIN (SELECT [Var_45].[Id] AS [Id], [Var_45].[LastName] AS [LastName], [Var_45].[Discriminator] AS [Discriminator]
FROM [dbo].[Employee] AS [Var_45]
WHERE ([Var_45].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent5] ON ([Extent5].[Discriminator] = N''Employee'') AND ([Extent1].[Employee_Id] = [Extent5].[Id])
LEFT OUTER JOIN (SELECT [Var_46].[Id] AS [Id], [Var_46].[EnterpriseId] AS [EnterpriseId], [Var_46].[Discriminator] AS [Discriminator]
FROM [dbo].[Employee] AS [Var_46]
WHERE ([Var_46].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent6] ON ([Extent6].[Discriminator] = N''Employee'') AND ([Extent1].[Employee_Id] = [Extent6].[Id])
LEFT OUTER JOIN (SELECT [Var_47].[Id] AS [Id], [Var_47].[Level] AS [Level], [Var_47].[Discriminator] AS [Discriminator]
FROM [dbo].[Employee] AS [Var_47]
WHERE ([Var_47].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent7] ON ([Extent7].[Discriminator] = N''Employee'') AND ([Extent1].[Employee_Id] = [Extent7].[Id])
LEFT OUTER JOIN (SELECT [Extent8].[FKEmployeeCvId] AS [FKEmployeeCvId], [Extent9].[Id] AS [Id], [Extent9].[Title] AS [Title], [Extent9].[CreatedDate] AS [CreatedDate], [Extent9].[CreatedBy] AS [CreatedBy], [Extent9].[UpdatedDate] AS [UpdatedDate], [Extent9].[UpdatedBy] AS [UpdatedBy], [Extent9].[IsDeleted] AS [IsDeleted], [Extent9].[TagType_Id] AS [TagType_Id], [Extent9].[ProjectExperience_Id] AS [ProjectExperience_Id]
FROM [dbo].[EmployeeTags] AS [Extent8]
INNER JOIN (SELECT [Var_48].[Id] AS [Id], [Var_48].[Title] AS [Title], [Var_48].[CreatedDate] AS [CreatedDate], [Var_48].[CreatedBy] AS [CreatedBy], [Var_48].[UpdatedDate] AS [UpdatedDate], [Var_48].[UpdatedBy] AS [UpdatedBy], [Var_48].[IsDeleted] AS [IsDeleted], [Var_48].[TagType_Id] AS [TagType_Id], [Var_48].[ProjectExperience_Id] AS [ProjectExperience_Id]
FROM [dbo].[Tag] AS [Var_48]
WHERE ([Var_48].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent9] ON [Extent9].[Id] = [Extent8].[FKTagId] ) AS [Join7] ON [Extent1].[Id] = [Join7].[FKEmployeeCvId]
WHERE (contains([Extent2].[FirstName], @p__linq__0)) OR (contains([Extent3].[LastName], @p__linq__1)) OR ( EXISTS (SELECT
1 AS [C1]
FROM [dbo].[ProjectExperience] AS [Extent10]
WHERE (([Extent10].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL)) AND ([Extent10].[Type] = N''Draft'') AND ([Extent1].[Id] = [Extent10].[EmployeeCv_Id]) AND ((contains([Extent10].[ProjectTitle], @p__linq__2)) OR (contains([Extent10].[Description], @p__linq__3)))
)) OR ( EXISTS (SELECT
1 AS [C1]
FROM [dbo].[EmployeeTags] AS [Extent11]
INNER JOIN (SELECT [Var_49].[Id] AS [Id], [Var_49].[Title] AS [Title]
FROM [dbo].[Tag] AS [Var_49]
WHERE ([Var_49].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent12] ON [Extent12].[Id] = [Extent11].[FKTagId]
WHERE ([Extent1].[Id] = [Extent11].[FKEmployeeCvId]) AND (contains([Extent12].[Title], @p__linq__4))
))
UNION ALL
SELECT
2 AS [C1],
[Extent13].[Id] AS [Id],
[Extent14].[Id] AS [Id1],
[Extent15].[Id] AS [Id2],
[Extent16].[Id] AS [Id3],
[Extent17].[Id] AS [Id4],
[Extent18].[Id] AS [Id5],
[Extent19].[Id] AS [Id6],
[Extent13].[Id] AS [Id7],
[Extent13].[Id] AS [Id8],
[Extent16].[FirstName] AS [FirstName],
[Extent17].[LastName] AS [LastName],
[Extent18].[EnterpriseId] AS [EnterpriseId],
[Extent19].[Level] AS [Level],
CAST(NULL AS int) AS [C2],
CAST(NULL AS int) AS [C3],
CAST(NULL AS varchar(1)) AS [C4],
CAST(NULL AS datetime2) AS [C5],
CAST(NULL AS varchar(1)) AS [C6],
CAST(NULL AS datetime2) AS [C7],
CAST(NULL AS varchar(1)) AS [C8],
CAST(NULL AS bit) AS [C9],
CAST(NULL AS int) AS [C10],
CAST(NULL AS int) AS [C11],
[Extent20].[Id] AS [Id9],
''4X0X'' AS [C12],
[Extent20].[Id] AS [Id10],
[Extent20].[ProjectTitle] AS [ProjectTitle],
[Extent20].[Description] AS [Description],
[Extent20].[CreatedDate] AS [CreatedDate],
[Extent20].[CreatedBy] AS [CreatedBy],
[Extent20].[UpdatedDate] AS [UpdatedDate],
[Extent20].[UpdatedBy] AS [UpdatedBy],
[Extent20].[IsDeleted] AS [IsDeleted],
[Extent20].[SequenceOrder] AS [SequenceOrder],
[Extent20].[EmployeeCv_Id] AS [EmployeeCv_Id],
[Extent20].[CvProfile_Id] AS [CvProfile_Id],
[Extent20].[AssociatedSchedulingProject_Id] AS [AssociatedSchedulingProject_Id],
[Extent20].[Customer_Id] AS [Customer_Id],
[Extent20].[Employee_Id] AS [Employee_Id]
FROM (SELECT [Var_50].[Id] AS [Id], [Var_50].[Employee_Id] AS [Employee_Id]
FROM [dbo].[EmployeeCv] AS [Var_50]
WHERE ([Var_50].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent13]
LEFT OUTER JOIN (SELECT [Var_51].[Id] AS [Id], [Var_51].[FirstName] AS [FirstName], [Var_51].[Discriminator] AS [Discriminator]
FROM [dbo].[Employee] AS [Var_51]
WHERE ([Var_51].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent14] ON ([Extent14].[Discriminator] = N''Employee'') AND ([Extent13].[Employee_Id] = [Extent14].[Id])
LEFT OUTER JOIN (SELECT [Var_52].[Id] AS [Id], [Var_52].[LastName] AS [LastName], [Var_52].[Discriminator] AS [Discriminator]
FROM [dbo].[Employee] AS [Var_52]
WHERE ([Var_52].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent15] ON ([Extent15].[Discriminator] = N''Employee'') AND ([Extent13].[Employee_Id] = [Extent15].[Id])
LEFT OUTER JOIN (SELECT [Var_53].[Id] AS [Id], [Var_53].[FirstName] AS [FirstName], [Var_53].[Discriminator] AS [Discriminator]
FROM [dbo].[Employee] AS [Var_53]
WHERE ([Var_53].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent16] ON ([Extent16].[Discriminator] = N''Employee'') AND ([Extent13].[Employee_Id] = [Extent16].[Id])
LEFT OUTER JOIN (SELECT [Var_54].[Id] AS [Id], [Var_54].[LastName] AS [LastName], [Var_54].[Discriminator] AS [Discriminator]
FROM [dbo].[Employee] AS [Var_54]
WHERE ([Var_54].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent17] ON ([Extent17].[Discriminator] = N''Employee'') AND ([Extent13].[Employee_Id] = [Extent17].[Id])
LEFT OUTER JOIN (SELECT [Var_55].[Id] AS [Id], [Var_55].[EnterpriseId] AS [EnterpriseId], [Var_55].[Discriminator] AS [Discriminator]
FROM [dbo].[Employee] AS [Var_55]
WHERE ([Var_55].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent18] ON ([Extent18].[Discriminator] = N''Employee'') AND ([Extent13].[Employee_Id] = [Extent18].[Id])
LEFT OUTER JOIN (SELECT [Var_56].[Id] AS [Id], [Var_56].[Level] AS [Level], [Var_56].[Discriminator] AS [Discriminator]
FROM [dbo].[Employee] AS [Var_56]
WHERE ([Var_56].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent19] ON ([Extent19].[Discriminator] = N''Employee'') AND ([Extent13].[Employee_Id] = [Extent19].[Id])
INNER JOIN (SELECT [Var_57].[Id] AS [Id], [Var_57].[ProjectTitle] AS [ProjectTitle], [Var_57].[Description] AS [Description], [Var_57].[CreatedDate] AS [CreatedDate], [Var_57].[CreatedBy] AS [CreatedBy], [Var_57].[UpdatedDate] AS [UpdatedDate], [Var_57].[UpdatedBy] AS [UpdatedBy], [Var_57].[IsDeleted] AS [IsDeleted], [Var_57].[SequenceOrder] AS [SequenceOrder], [Var_57].[EmployeeCv_Id] AS [EmployeeCv_Id], [Var_57].[CvProfile_Id] AS [CvProfile_Id], [Var_57].[AssociatedSchedulingProject_Id] AS [AssociatedSchedulingProject_Id], [Var_57].[Customer_Id] AS [Customer_Id], [Var_57].[Employee_Id] AS [Employee_Id], [Var_57].[Type] AS [Type]
FROM [dbo].[ProjectExperience] AS [Var_57]
WHERE ([Var_57].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent20] ON ([Extent20].[Type] = N''Draft'') AND ([Extent13].[Id] = [Extent20].[EmployeeCv_Id])
WHERE (contains([Extent14].[FirstName], @p__linq__0)) OR (contains([Extent15].[LastName], @p__linq__1)) OR ( EXISTS (SELECT
1 AS [C1]
FROM [dbo].[ProjectExperience] AS [Extent21]
WHERE (([Extent21].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL)) AND ([Extent21].[Type] = N''Draft'') AND ([Extent13].[Id] = [Extent21].[EmployeeCv_Id]) AND ((contains([Extent21].[ProjectTitle], @p__linq__2)) OR (contains([Extent21].[Description], @p__linq__3)))
)) OR ( EXISTS (SELECT
1 AS [C1]
FROM [dbo].[EmployeeTags] AS [Extent22]
INNER JOIN (SELECT [Var_58].[Id] AS [Id], [Var_58].[Title] AS [Title]
FROM [dbo].[Tag] AS [Var_58]
WHERE ([Var_58].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent23] ON [Extent23].[Id] = [Extent22].[FKTagId]
WHERE ([Extent13].[Id] = [Extent22].[FKEmployeeCvId]) AND (contains([Extent23].[Title], @p__linq__4))
))) AS [UnionAll1]
ORDER BY [UnionAll1].[Id] ASC, [UnionAll1].[Id1] ASC, [UnionAll1].[Id2] ASC, [UnionAll1].[Id3] ASC, [UnionAll1].[Id4] ASC, [UnionAll1].[Id5] ASC, [UnionAll1].[Id6] ASC, [UnionAll1].[C1] ASC',N'@DynamicFilterParam_IsDeleted_IsDeleted bit,@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled bit,@p__linq__0 char(4096),@p__linq__1 char(4096),@p__linq__2 char(4096),@p__linq__3 char(4096),@p__linq__4 char(4096)',@DynamicFilterParam_IsDeleted_IsDeleted=0,@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled=NULL,@p__linq__0='(sitecore)',@p__linq__1='(sitecore)',
@p__linq__2='(sitecore)',
@p__linq__3='(sitecore) ',@p__linq__4='(sitecore) '
当我在 SQL MS 中执行此查询时,它给了我同样的错误。
即使我可以像这样直接在 table 上成功执行包含查询:
select * from Employee where contains(FirstName,'"John*"')
这个 Linq 有效:
var employeeCV = _context.Employees.Where(x => x.FirstName.Contains(SearchQuery.Keyword)).ToList();
如果您使用的是 MS SQL 服务器,看来您必须先在数据库中创建全文索引 - 请参阅此 link https://msdn.microsoft.com/en-us/library/ms187317.aspx if you want to do this via sql statements, otherwise see this link - https://technet.microsoft.com/en-us/library/aa197912(v=sql.80).aspx - 如果您想通过 UI
做到这一点
您能否确认您为参与包含函数
的所有列启用了全文索引
select * from Employee where contains((FirstName,LastName),'"John*"')
select * from Tag where contains(Title,'"John*"')
您的问题是您尝试 运行 全文不是来自 Employees
table,而是 Extent2
,即 SELECT something FROM Employees WHERE ...
并且它没有全文索引。您将不得不重写您的 linq 查询或使用 T-SQL 而不是 linq.
(SELECT [Var_42].[Id] AS [Id], [Var_42].[FirstName] AS [FirstName],
[Var_42].[Discriminator] AS [Discriminator]
FROM [dbo].[Employee] AS [Var_42]
WHERE ([Var_42].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR
(@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) )
AS [Extent2]
我建议您尝试像这样重写您的 linq 查询:
ListOfEmployees = from cvs in _context.EmployeeCvs.Include(x => x.Employee)
where _Context.Employees.Any(
e=>e.FirstName.Contains(SearchQuery.Keyword)
&& e.EmployeeID == cvs.EmployeeID
))
... etc
这应该会生成一个简单的 EXISTS
语句,应该可以正常工作。
最好使用查询语法,因为你可以命名你的子查询。
EF 为您造成这种“混乱”的原因是因为您使用 Dynamic filters。
[Var_58].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted
如果您尝试禁用动态过滤器:
_context.DisableAllFilters();
它现在对你没有帮助,因为它只是在生成的查询中设置变量 @DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled
,但查询仍将包含 [Var_xx]
子查询,因为 EntityFramework.DynamicFilters
覆盖了一些方法Entity Framework。参见 this link。
为什么动态过滤器会导致问题?
When I specify additional filters on entity queries (using linq's
.Where() clause, for example), those additional filters cause EF to
create sub-tables in the query.
因此动态过滤器会创建子查询,您会遇到异常,它也是 well described here。有一个类似的解决方法推荐:
The workaround I'm currently using (which seems to work) is to always
force the Full Text Index predicate into a separate sub query so the
predicate is always executed against the base table rather than an
intermediate result set.
因此您应该尝试将所有使用全文索引的条件转换为单独的 EXISTS 语句。
我最终像这样重写 LINQ 来解决问题:
var listOfEmployeeCV = from cvs in _context.EmployeeCvs.Include(x => x.Employee).Include(x=>x.Tags)
.Include(x=>x.ProjectExperiences)
where _context.Employees.Any(
e => e.FirstName.Contains(SearchQuery.Keyword)
&& e.Id == cvs.Employee.Id
) || (_context.Tags.Any(t=>t.Title.Contains(SearchQuery.Keyword) && cvs.Tags.Contains(t)))
|| (_context.ProjectExperiences.Any(pe=>(pe.ProjectTitle.Contains(SearchQuery.Keyword)
|| pe.Description.Contains(SearchQuery.Keyword)) &&
cvs.ProjectExperiences.Contains(pe)))
select new
EmployeeCvDTO
{
Employee = new EmployeeDTO
{
FirstName = cvs.Employee.FirstName,
LastName = cvs.Employee.LastName,
EnterpriseId = cvs.Employee.EnterpriseId,
Level = cvs.Employee.Level
//ProfileImageData = x.Employee.ProfileImageData
},
Tags = cvs.Tags,
ProjectExperiences = cvs.ProjectExperiences,
};
使用原始 sql 到 Entity Framework,它有效。
rtEntities rv = new rtEntities();
string query = string.Format("SELECT FT_TBL.ID, FT_TBL.Description, KEY_TBL.RANK FROM tbl_user AS FT_TBL INNER JOIN FREETEXTTABLE(tbl_user, Description, '(free text)', 5 ) AS KEY_TBL ON FT_TBL.ID = KEY_TBL.[KEY]");
var data = rv.Database.SqlQuery<userDetails>(query).ToList();
GridView1.DataSource = data;
GridView1.DataBind();
我正在尝试使用 EF 6.0 执行全文索引搜索。我正在使用 IDbCommandInterceptor (http://www.entityframework.info/Home/FullTextSearch) 执行全文搜索,但它抛出了这个异常:
Cannot use a CONTAINS or FREETEXT predicate on column 'FirstName' because it is not full-text indexed.
Linq 查询:
ListOfEmployees = _context.EmployeeCvs.Include(x => x.Employee)
.Include(x => x.Tags)
.Include(x => x.ProjectExperiences)
.Where(x => x.Employee.FirstName.Contains(SearchQuery.Keyword) || x.Employee.LastName.Contains(SearchQuery.Keyword) || x.ProjectExperiences.Any(y => y.ProjectTitle.Contains(SearchQuery.Keyword) || y.Description.Contains(SearchQuery.Keyword)) || x.Tags.Any(t => t.Title.Contains(SearchQuery.Keyword)))
.ToList();
下面是 EF 执行的查询:
exec sp_executesql N'SELECT
[UnionAll1].[Id] AS [C1],
[UnionAll1].[Id1] AS [C2],
[UnionAll1].[Id2] AS [C3],
[UnionAll1].[Id3] AS [C4],
[UnionAll1].[Id4] AS [C5],
[UnionAll1].[Id5] AS [C6],
[UnionAll1].[Id6] AS [C7],
[UnionAll1].[Id7] AS [C8],
[UnionAll1].[Id8] AS [C9],
[UnionAll1].[FirstName] AS [C10],
[UnionAll1].[LastName] AS [C11],
[UnionAll1].[EnterpriseId] AS [C12],
[UnionAll1].[Level] AS [C13],
[UnionAll1].[C1] AS [C14],
[UnionAll1].[Id9] AS [C15],
[UnionAll1].[Id10] AS [C16],
[UnionAll1].[Title] AS [C17],
[UnionAll1].[CreatedDate] AS [C18],
[UnionAll1].[CreatedBy] AS [C19],
[UnionAll1].[UpdatedDate] AS [C20],
[UnionAll1].[UpdatedBy] AS [C21],
[UnionAll1].[IsDeleted] AS [C22],
[UnionAll1].[TagType_Id] AS [C23],
[UnionAll1].[ProjectExperience_Id] AS [C24],
[UnionAll1].[C2] AS [C25],
[UnionAll1].[C3] AS [C26],
[UnionAll1].[C4] AS [C27],
[UnionAll1].[C5] AS [C28],
[UnionAll1].[C6] AS [C29],
[UnionAll1].[C7] AS [C30],
[UnionAll1].[C8] AS [C31],
[UnionAll1].[C9] AS [C32],
[UnionAll1].[C10] AS [C33],
[UnionAll1].[C11] AS [C34],
[UnionAll1].[C12] AS [C35],
[UnionAll1].[C13] AS [C36],
[UnionAll1].[C14] AS [C37],
[UnionAll1].[C15] AS [C38],
[UnionAll1].[C16] AS [C39],
[UnionAll1].[C17] AS [C40]
FROM (SELECT
CASE WHEN ([Join7].[FKEmployeeCvId] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1],
[Extent1].[Id] AS [Id],
[Extent2].[Id] AS [Id1],
[Extent3].[Id] AS [Id2],
[Extent4].[Id] AS [Id3],
[Extent5].[Id] AS [Id4],
[Extent6].[Id] AS [Id5],
[Extent7].[Id] AS [Id6],
[Extent1].[Id] AS [Id7],
[Extent1].[Id] AS [Id8],
[Extent4].[FirstName] AS [FirstName],
[Extent5].[LastName] AS [LastName],
[Extent6].[EnterpriseId] AS [EnterpriseId],
[Extent7].[Level] AS [Level],
[Join7].[Id] AS [Id9],
[Join7].[Id] AS [Id10],
[Join7].[Title] AS [Title],
[Join7].[CreatedDate] AS [CreatedDate],
[Join7].[CreatedBy] AS [CreatedBy],
[Join7].[UpdatedDate] AS [UpdatedDate],
[Join7].[UpdatedBy] AS [UpdatedBy],
[Join7].[IsDeleted] AS [IsDeleted],
[Join7].[TagType_Id] AS [TagType_Id],
[Join7].[ProjectExperience_Id] AS [ProjectExperience_Id],
CAST(NULL AS int) AS [C2],
CAST(NULL AS varchar(1)) AS [C3],
CAST(NULL AS int) AS [C4],
CAST(NULL AS varchar(1)) AS [C5],
CAST(NULL AS varchar(1)) AS [C6],
CAST(NULL AS datetime2) AS [C7],
CAST(NULL AS varchar(1)) AS [C8],
CAST(NULL AS datetime2) AS [C9],
CAST(NULL AS varchar(1)) AS [C10],
CAST(NULL AS bit) AS [C11],
CAST(NULL AS int) AS [C12],
CAST(NULL AS int) AS [C13],
CAST(NULL AS int) AS [C14],
CAST(NULL AS int) AS [C15],
CAST(NULL AS int) AS [C16],
CAST(NULL AS int) AS [C17]
FROM (SELECT [Var_41].[Id] AS [Id], [Var_41].[Employee_Id] AS [Employee_Id]
FROM [dbo].[EmployeeCv] AS [Var_41]
WHERE ([Var_41].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent1]
LEFT OUTER JOIN (SELECT [Var_42].[Id] AS [Id], [Var_42].[FirstName] AS [FirstName], [Var_42].[Discriminator] AS [Discriminator]
FROM [dbo].[Employee] AS [Var_42]
WHERE ([Var_42].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent2] ON ([Extent2].[Discriminator] = N''Employee'') AND ([Extent1].[Employee_Id] = [Extent2].[Id])
LEFT OUTER JOIN (SELECT [Var_43].[Id] AS [Id], [Var_43].[LastName] AS [LastName], [Var_43].[Discriminator] AS [Discriminator]
FROM [dbo].[Employee] AS [Var_43]
WHERE ([Var_43].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent3] ON ([Extent3].[Discriminator] = N''Employee'') AND ([Extent1].[Employee_Id] = [Extent3].[Id])
LEFT OUTER JOIN (SELECT [Var_44].[Id] AS [Id], [Var_44].[FirstName] AS [FirstName], [Var_44].[Discriminator] AS [Discriminator]
FROM [dbo].[Employee] AS [Var_44]
WHERE ([Var_44].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent4] ON ([Extent4].[Discriminator] = N''Employee'') AND ([Extent1].[Employee_Id] = [Extent4].[Id])
LEFT OUTER JOIN (SELECT [Var_45].[Id] AS [Id], [Var_45].[LastName] AS [LastName], [Var_45].[Discriminator] AS [Discriminator]
FROM [dbo].[Employee] AS [Var_45]
WHERE ([Var_45].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent5] ON ([Extent5].[Discriminator] = N''Employee'') AND ([Extent1].[Employee_Id] = [Extent5].[Id])
LEFT OUTER JOIN (SELECT [Var_46].[Id] AS [Id], [Var_46].[EnterpriseId] AS [EnterpriseId], [Var_46].[Discriminator] AS [Discriminator]
FROM [dbo].[Employee] AS [Var_46]
WHERE ([Var_46].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent6] ON ([Extent6].[Discriminator] = N''Employee'') AND ([Extent1].[Employee_Id] = [Extent6].[Id])
LEFT OUTER JOIN (SELECT [Var_47].[Id] AS [Id], [Var_47].[Level] AS [Level], [Var_47].[Discriminator] AS [Discriminator]
FROM [dbo].[Employee] AS [Var_47]
WHERE ([Var_47].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent7] ON ([Extent7].[Discriminator] = N''Employee'') AND ([Extent1].[Employee_Id] = [Extent7].[Id])
LEFT OUTER JOIN (SELECT [Extent8].[FKEmployeeCvId] AS [FKEmployeeCvId], [Extent9].[Id] AS [Id], [Extent9].[Title] AS [Title], [Extent9].[CreatedDate] AS [CreatedDate], [Extent9].[CreatedBy] AS [CreatedBy], [Extent9].[UpdatedDate] AS [UpdatedDate], [Extent9].[UpdatedBy] AS [UpdatedBy], [Extent9].[IsDeleted] AS [IsDeleted], [Extent9].[TagType_Id] AS [TagType_Id], [Extent9].[ProjectExperience_Id] AS [ProjectExperience_Id]
FROM [dbo].[EmployeeTags] AS [Extent8]
INNER JOIN (SELECT [Var_48].[Id] AS [Id], [Var_48].[Title] AS [Title], [Var_48].[CreatedDate] AS [CreatedDate], [Var_48].[CreatedBy] AS [CreatedBy], [Var_48].[UpdatedDate] AS [UpdatedDate], [Var_48].[UpdatedBy] AS [UpdatedBy], [Var_48].[IsDeleted] AS [IsDeleted], [Var_48].[TagType_Id] AS [TagType_Id], [Var_48].[ProjectExperience_Id] AS [ProjectExperience_Id]
FROM [dbo].[Tag] AS [Var_48]
WHERE ([Var_48].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent9] ON [Extent9].[Id] = [Extent8].[FKTagId] ) AS [Join7] ON [Extent1].[Id] = [Join7].[FKEmployeeCvId]
WHERE (contains([Extent2].[FirstName], @p__linq__0)) OR (contains([Extent3].[LastName], @p__linq__1)) OR ( EXISTS (SELECT
1 AS [C1]
FROM [dbo].[ProjectExperience] AS [Extent10]
WHERE (([Extent10].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL)) AND ([Extent10].[Type] = N''Draft'') AND ([Extent1].[Id] = [Extent10].[EmployeeCv_Id]) AND ((contains([Extent10].[ProjectTitle], @p__linq__2)) OR (contains([Extent10].[Description], @p__linq__3)))
)) OR ( EXISTS (SELECT
1 AS [C1]
FROM [dbo].[EmployeeTags] AS [Extent11]
INNER JOIN (SELECT [Var_49].[Id] AS [Id], [Var_49].[Title] AS [Title]
FROM [dbo].[Tag] AS [Var_49]
WHERE ([Var_49].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent12] ON [Extent12].[Id] = [Extent11].[FKTagId]
WHERE ([Extent1].[Id] = [Extent11].[FKEmployeeCvId]) AND (contains([Extent12].[Title], @p__linq__4))
))
UNION ALL
SELECT
2 AS [C1],
[Extent13].[Id] AS [Id],
[Extent14].[Id] AS [Id1],
[Extent15].[Id] AS [Id2],
[Extent16].[Id] AS [Id3],
[Extent17].[Id] AS [Id4],
[Extent18].[Id] AS [Id5],
[Extent19].[Id] AS [Id6],
[Extent13].[Id] AS [Id7],
[Extent13].[Id] AS [Id8],
[Extent16].[FirstName] AS [FirstName],
[Extent17].[LastName] AS [LastName],
[Extent18].[EnterpriseId] AS [EnterpriseId],
[Extent19].[Level] AS [Level],
CAST(NULL AS int) AS [C2],
CAST(NULL AS int) AS [C3],
CAST(NULL AS varchar(1)) AS [C4],
CAST(NULL AS datetime2) AS [C5],
CAST(NULL AS varchar(1)) AS [C6],
CAST(NULL AS datetime2) AS [C7],
CAST(NULL AS varchar(1)) AS [C8],
CAST(NULL AS bit) AS [C9],
CAST(NULL AS int) AS [C10],
CAST(NULL AS int) AS [C11],
[Extent20].[Id] AS [Id9],
''4X0X'' AS [C12],
[Extent20].[Id] AS [Id10],
[Extent20].[ProjectTitle] AS [ProjectTitle],
[Extent20].[Description] AS [Description],
[Extent20].[CreatedDate] AS [CreatedDate],
[Extent20].[CreatedBy] AS [CreatedBy],
[Extent20].[UpdatedDate] AS [UpdatedDate],
[Extent20].[UpdatedBy] AS [UpdatedBy],
[Extent20].[IsDeleted] AS [IsDeleted],
[Extent20].[SequenceOrder] AS [SequenceOrder],
[Extent20].[EmployeeCv_Id] AS [EmployeeCv_Id],
[Extent20].[CvProfile_Id] AS [CvProfile_Id],
[Extent20].[AssociatedSchedulingProject_Id] AS [AssociatedSchedulingProject_Id],
[Extent20].[Customer_Id] AS [Customer_Id],
[Extent20].[Employee_Id] AS [Employee_Id]
FROM (SELECT [Var_50].[Id] AS [Id], [Var_50].[Employee_Id] AS [Employee_Id]
FROM [dbo].[EmployeeCv] AS [Var_50]
WHERE ([Var_50].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent13]
LEFT OUTER JOIN (SELECT [Var_51].[Id] AS [Id], [Var_51].[FirstName] AS [FirstName], [Var_51].[Discriminator] AS [Discriminator]
FROM [dbo].[Employee] AS [Var_51]
WHERE ([Var_51].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent14] ON ([Extent14].[Discriminator] = N''Employee'') AND ([Extent13].[Employee_Id] = [Extent14].[Id])
LEFT OUTER JOIN (SELECT [Var_52].[Id] AS [Id], [Var_52].[LastName] AS [LastName], [Var_52].[Discriminator] AS [Discriminator]
FROM [dbo].[Employee] AS [Var_52]
WHERE ([Var_52].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent15] ON ([Extent15].[Discriminator] = N''Employee'') AND ([Extent13].[Employee_Id] = [Extent15].[Id])
LEFT OUTER JOIN (SELECT [Var_53].[Id] AS [Id], [Var_53].[FirstName] AS [FirstName], [Var_53].[Discriminator] AS [Discriminator]
FROM [dbo].[Employee] AS [Var_53]
WHERE ([Var_53].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent16] ON ([Extent16].[Discriminator] = N''Employee'') AND ([Extent13].[Employee_Id] = [Extent16].[Id])
LEFT OUTER JOIN (SELECT [Var_54].[Id] AS [Id], [Var_54].[LastName] AS [LastName], [Var_54].[Discriminator] AS [Discriminator]
FROM [dbo].[Employee] AS [Var_54]
WHERE ([Var_54].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent17] ON ([Extent17].[Discriminator] = N''Employee'') AND ([Extent13].[Employee_Id] = [Extent17].[Id])
LEFT OUTER JOIN (SELECT [Var_55].[Id] AS [Id], [Var_55].[EnterpriseId] AS [EnterpriseId], [Var_55].[Discriminator] AS [Discriminator]
FROM [dbo].[Employee] AS [Var_55]
WHERE ([Var_55].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent18] ON ([Extent18].[Discriminator] = N''Employee'') AND ([Extent13].[Employee_Id] = [Extent18].[Id])
LEFT OUTER JOIN (SELECT [Var_56].[Id] AS [Id], [Var_56].[Level] AS [Level], [Var_56].[Discriminator] AS [Discriminator]
FROM [dbo].[Employee] AS [Var_56]
WHERE ([Var_56].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent19] ON ([Extent19].[Discriminator] = N''Employee'') AND ([Extent13].[Employee_Id] = [Extent19].[Id])
INNER JOIN (SELECT [Var_57].[Id] AS [Id], [Var_57].[ProjectTitle] AS [ProjectTitle], [Var_57].[Description] AS [Description], [Var_57].[CreatedDate] AS [CreatedDate], [Var_57].[CreatedBy] AS [CreatedBy], [Var_57].[UpdatedDate] AS [UpdatedDate], [Var_57].[UpdatedBy] AS [UpdatedBy], [Var_57].[IsDeleted] AS [IsDeleted], [Var_57].[SequenceOrder] AS [SequenceOrder], [Var_57].[EmployeeCv_Id] AS [EmployeeCv_Id], [Var_57].[CvProfile_Id] AS [CvProfile_Id], [Var_57].[AssociatedSchedulingProject_Id] AS [AssociatedSchedulingProject_Id], [Var_57].[Customer_Id] AS [Customer_Id], [Var_57].[Employee_Id] AS [Employee_Id], [Var_57].[Type] AS [Type]
FROM [dbo].[ProjectExperience] AS [Var_57]
WHERE ([Var_57].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent20] ON ([Extent20].[Type] = N''Draft'') AND ([Extent13].[Id] = [Extent20].[EmployeeCv_Id])
WHERE (contains([Extent14].[FirstName], @p__linq__0)) OR (contains([Extent15].[LastName], @p__linq__1)) OR ( EXISTS (SELECT
1 AS [C1]
FROM [dbo].[ProjectExperience] AS [Extent21]
WHERE (([Extent21].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL)) AND ([Extent21].[Type] = N''Draft'') AND ([Extent13].[Id] = [Extent21].[EmployeeCv_Id]) AND ((contains([Extent21].[ProjectTitle], @p__linq__2)) OR (contains([Extent21].[Description], @p__linq__3)))
)) OR ( EXISTS (SELECT
1 AS [C1]
FROM [dbo].[EmployeeTags] AS [Extent22]
INNER JOIN (SELECT [Var_58].[Id] AS [Id], [Var_58].[Title] AS [Title]
FROM [dbo].[Tag] AS [Var_58]
WHERE ([Var_58].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent23] ON [Extent23].[Id] = [Extent22].[FKTagId]
WHERE ([Extent13].[Id] = [Extent22].[FKEmployeeCvId]) AND (contains([Extent23].[Title], @p__linq__4))
))) AS [UnionAll1]
ORDER BY [UnionAll1].[Id] ASC, [UnionAll1].[Id1] ASC, [UnionAll1].[Id2] ASC, [UnionAll1].[Id3] ASC, [UnionAll1].[Id4] ASC, [UnionAll1].[Id5] ASC, [UnionAll1].[Id6] ASC, [UnionAll1].[C1] ASC',N'@DynamicFilterParam_IsDeleted_IsDeleted bit,@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled bit,@p__linq__0 char(4096),@p__linq__1 char(4096),@p__linq__2 char(4096),@p__linq__3 char(4096),@p__linq__4 char(4096)',@DynamicFilterParam_IsDeleted_IsDeleted=0,@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled=NULL,@p__linq__0='(sitecore)',@p__linq__1='(sitecore)',
@p__linq__2='(sitecore)',
@p__linq__3='(sitecore) ',@p__linq__4='(sitecore) '
当我在 SQL MS 中执行此查询时,它给了我同样的错误。 即使我可以像这样直接在 table 上成功执行包含查询:
select * from Employee where contains(FirstName,'"John*"')
这个 Linq 有效:
var employeeCV = _context.Employees.Where(x => x.FirstName.Contains(SearchQuery.Keyword)).ToList();
如果您使用的是 MS SQL 服务器,看来您必须先在数据库中创建全文索引 - 请参阅此 link https://msdn.microsoft.com/en-us/library/ms187317.aspx if you want to do this via sql statements, otherwise see this link - https://technet.microsoft.com/en-us/library/aa197912(v=sql.80).aspx - 如果您想通过 UI
做到这一点您能否确认您为参与包含函数
的所有列启用了全文索引select * from Employee where contains((FirstName,LastName),'"John*"')
select * from Tag where contains(Title,'"John*"')
您的问题是您尝试 运行 全文不是来自 Employees
table,而是 Extent2
,即 SELECT something FROM Employees WHERE ...
并且它没有全文索引。您将不得不重写您的 linq 查询或使用 T-SQL 而不是 linq.
(SELECT [Var_42].[Id] AS [Id], [Var_42].[FirstName] AS [FirstName], [Var_42].[Discriminator] AS [Discriminator] FROM [dbo].[Employee] AS [Var_42] WHERE ([Var_42].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted) OR (@DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent2]
我建议您尝试像这样重写您的 linq 查询:
ListOfEmployees = from cvs in _context.EmployeeCvs.Include(x => x.Employee)
where _Context.Employees.Any(
e=>e.FirstName.Contains(SearchQuery.Keyword)
&& e.EmployeeID == cvs.EmployeeID
))
... etc
这应该会生成一个简单的 EXISTS
语句,应该可以正常工作。
最好使用查询语法,因为你可以命名你的子查询。
EF 为您造成这种“混乱”的原因是因为您使用 Dynamic filters。
[Var_58].[IsDeleted] = @DynamicFilterParam_IsDeleted_IsDeleted
如果您尝试禁用动态过滤器:
_context.DisableAllFilters();
它现在对你没有帮助,因为它只是在生成的查询中设置变量 @DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled
,但查询仍将包含 [Var_xx]
子查询,因为 EntityFramework.DynamicFilters
覆盖了一些方法Entity Framework。参见 this link。
为什么动态过滤器会导致问题?
When I specify additional filters on entity queries (using linq's .Where() clause, for example), those additional filters cause EF to create sub-tables in the query.
因此动态过滤器会创建子查询,您会遇到异常,它也是 well described here。有一个类似的解决方法推荐:
The workaround I'm currently using (which seems to work) is to always force the Full Text Index predicate into a separate sub query so the predicate is always executed against the base table rather than an intermediate result set.
因此您应该尝试将所有使用全文索引的条件转换为单独的 EXISTS 语句。
我最终像这样重写 LINQ 来解决问题:
var listOfEmployeeCV = from cvs in _context.EmployeeCvs.Include(x => x.Employee).Include(x=>x.Tags)
.Include(x=>x.ProjectExperiences)
where _context.Employees.Any(
e => e.FirstName.Contains(SearchQuery.Keyword)
&& e.Id == cvs.Employee.Id
) || (_context.Tags.Any(t=>t.Title.Contains(SearchQuery.Keyword) && cvs.Tags.Contains(t)))
|| (_context.ProjectExperiences.Any(pe=>(pe.ProjectTitle.Contains(SearchQuery.Keyword)
|| pe.Description.Contains(SearchQuery.Keyword)) &&
cvs.ProjectExperiences.Contains(pe)))
select new
EmployeeCvDTO
{
Employee = new EmployeeDTO
{
FirstName = cvs.Employee.FirstName,
LastName = cvs.Employee.LastName,
EnterpriseId = cvs.Employee.EnterpriseId,
Level = cvs.Employee.Level
//ProfileImageData = x.Employee.ProfileImageData
},
Tags = cvs.Tags,
ProjectExperiences = cvs.ProjectExperiences,
};
使用原始 sql 到 Entity Framework,它有效。
rtEntities rv = new rtEntities();
string query = string.Format("SELECT FT_TBL.ID, FT_TBL.Description, KEY_TBL.RANK FROM tbl_user AS FT_TBL INNER JOIN FREETEXTTABLE(tbl_user, Description, '(free text)', 5 ) AS KEY_TBL ON FT_TBL.ID = KEY_TBL.[KEY]");
var data = rv.Database.SqlQuery<userDetails>(query).ToList();
GridView1.DataSource = data;
GridView1.DataBind();