I am trying to perform full text index search using EF 6.0. I am using IDbCommandInterceptor (http://www.entityframework.info/Home/FullTextSearch) perform Full text search but it is throwing me this exception:
Cannot use a CONTAINS or FREETEXT predicate on column 'FirstName'
because it is not full-text indexed.
Linq query:
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();
Below is the query that is executed by 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) '
When I am executing this query in the SQL MS it is giving me same error.
Even though I can successfully execute the contains query directly on the table like this:
select * from Employee where contains(FirstName,'"John*"')
This Linq works:
var employeeCV = _context.Employees.Where(x => x.FirstName.Contains(SearchQuery.Keyword)).ToList();
Your problem is that you are trying to run fulltext not on from Employees table, but on a Extent2, i.e. SELECT something FROM Employees WHERE ... and it is not full-text indexed. You will have to rewrite your linq query or do it in T-SQL instead of 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]
I suggest that you try to rewrite your linq query like this:
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
This should generate a simple EXISTS statement which should work OK.
It is better to use query syntax, because you can name your subqueries.
The reason why EF is doing this "mess" for you is because you use Dynamic filters.
[Var_58].[IsDeleted] = #DynamicFilterParam_IsDeleted_IsDeleted
If you try to disable the Dynamic filters:
_context.DisableAllFilters();
it will not help you now, since it just sets the variable #DynamicFilterParam_IsDeleted_DynamicFilterIsDisabled in the generated query, but the query still will contain [Var_xx] subqueries, because EntityFramework.DynamicFilters overrides some methods of Entity Framework. See this link.
Why do dynamic filters cause problems?
The reason is mentioned here:
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.
So Dynamic filters create subqueries and there you get your exception, it is also well described here. There is a similar workaround recommended:
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.
So you should try to convert all the conditions that are using full-text indexes to separate EXISTS statements.
It looks like you have to create a full-text index in your database first, if you're using MS SQL Server - see this 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 - if you want to do this via UI
Can you please confirm that you have full-text indexing enabled for ALL columns that participate in Contains function
select * from Employee where contains((FirstName,LastName),'"John*"')
select * from Tag where contains(Title,'"John*"')
I end up rewriting the LINQ like this to fix the problem:
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,
};
Use raw sql through Entity Framework, it works.
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();
Related
I have an entity framework query to join applications with ethnicity table and group by ethnicity (Id and options) and then get the total count for each ethnicity and then get the individual counts based on status {open, Closed, Draft.. etc) with Iqueryable as I will need to use pagination for this query to get first 'x' or go to page 'y' so I cannot do toList and then get the values.
The current EF query is very slow and it's taking more time.
Can anyone help me to achieve the same result in a better way if possible?
var query = from app in Context.Application
join eth in Context.Ethnicities on app.EthnicityId equals eth.EthnicityId
group app by new
{
eth.EthnicityId,
eth.EthnicityOptions
}
into ethAgg
select new EthnicityView
{
Id = ethAgg.Key.EthnicityId,
Ethnicity = ethAgg.Key.EthnicityOptions,
Total = ethAgg.Count(),
Closed = ethAgg.Count(p => p.Closed),
Draft = ethAgg.Count(p => p.Draft ),
Inprogress = ethAgg.Count(p => p.Inprogress ),
Waiting = ethAgg.Count(p => p.Waiting),
Open = ethAgg.Count(p => p.Open )
};
Generated Sql
SELECT TOP (10)
[Project7].[EthnicityID] AS [EthnicityID],
[Project7].[C2] AS [C1],
[Project7].[C1] AS [C2],
[Project7].[C3] AS [C3],
[Project7].[C4] AS [C4],
[Project7].[C5] AS [C5],
[Project7].[C6] AS [C6],
[Project7].[C7] AS [C7]
FROM ( SELECT
[Project6].[C1] AS [C1],
[Project6].[EthnicityID] AS [EthnicityID],
[Project6].[EthnicityOptions] AS [C2],
[Project6].[C2] AS [C3],
[Project6].[C3] AS [C4],
[Project6].[C4] AS [C5],
[Project6].[C5] AS [C6],
[Project6].[C6] AS [C7]
FROM ( SELECT
[Project5].[C1] AS [C1],
[Project5].[EthnicityID] AS [EthnicityID],
[Project5].[EthnicityOptions] AS [EthnicityOptions],
[Project5].[C2] AS [C2],
[Project5].[C3] AS [C3],
[Project5].[C4] AS [C4],
[Project5].[C5] AS [C5],
(SELECT
COUNT(1) AS [A1]
FROM [dbo].[Application] AS [Extent16]
INNER JOIN [dbo].[Ethnicity] AS [Extent18] ON [Extent16].[EthnicityID] = [Extent18].[EthnicityID]
WHERE ([Extent16].[Closed] = 1)
FROM ( SELECT
[Project4].[C1] AS [C1],
[Project4].[EthnicityID] AS [EthnicityID],
[Project4].[EthnicityOptions] AS [EthnicityOptions],
[Project4].[C2] AS [C2],
[Project4].[C3] AS [C3],
[Project4].[C4] AS [C4],
(SELECT
COUNT(1) AS [A1]
FROM [dbo].[Application] AS [Extent13]
INNER JOIN [dbo].[Ethnicity] AS [Extent15] ON [Extent13].[EthnicityID] = [Extent15].[EthnicityID]
WHERE ([Extent13].[Closed] = 1)
FROM ( SELECT
[Project3].[C1] AS [C1],
[Project3].[EthnicityID] AS [EthnicityID],
[Project3].[EthnicityOptions] AS [EthnicityOptions],
[Project3].[C2] AS [C2],
[Project3].[C3] AS [C3],
(SELECT
COUNT(1) AS [A1]
FROM [dbo].[Application] AS [Extent10]
INNER JOIN [dbo].[Ethnicity] AS [Extent12] ON [Extent10].[EthnicityID] = [Extent12].[EthnicityID]
WHERE ([Extent10].[Draft] = 1)
FROM ( SELECT
[Project2].[C1] AS [C1],
[Project2].[EthnicityID] AS [EthnicityID],
[Project2].[EthnicityOptions] AS [EthnicityOptions],
[Project2].[C2] AS [C2],
(SELECT
COUNT(1) AS [A1]
FROM [dbo].[Application] AS [Extent7]
INNER JOIN [dbo].[Ethnicity] AS [Extent9] ON [Extent7].[EthnicityID] = [Extent9].[EthnicityID]
WHERE ([Extent7].[Inprogress] = 1)
FROM ( SELECT
[Project1].[C1] AS [C1],
[Project1].[EthnicityID] AS [EthnicityID],
[Project1].[EthnicityOptions] AS [EthnicityOptions],
(SELECT
COUNT(1) AS [A1]
FROM [dbo].[Application] AS [Extent4]
INNER JOIN [dbo].[Ethnicity] AS [Extent6] ON [Extent4].[EthnicityID] = [Extent6].[EthnicityID]
WHERE ([Extent4].[Waiting] = 1)
FROM ( SELECT
[GroupBy1].[A1] AS [C1],
[GroupBy1].[K1] AS [EthnicityID],
[GroupBy1].[K2] AS [EthnicityOptions]
FROM ( SELECT
[Extent3].[EthnicityID] AS [K1],
[Extent3].[EthnicityOptions] AS [K2],
COUNT(1) AS [A1]
FROM [dbo].[Application] AS [Extent1]
INNER JOIN [dbo].[Ethnicity] AS [Extent3] ON [Extent1].[EthnicityID] = [Extent3].[EthnicityID]
GROUP BY [Extent3].[EthnicityID], [Extent3].[EthnicityOptions]
) AS [GroupBy1]
) AS [Project1]
) AS [Project2]
) AS [Project3]
) AS [Project4]
) AS [Project5]
) AS [Project6]
) AS [Project7]
ORDER BY [Project7].[EthnicityID] ASC
As there is no way we could achieve this from entity framework.
I tried moving this query to a stored procedure and split the individual counts and invoke that stored proc from entity framework.
We have a new production line in our factory which has a bunch of testers on. These testers are running LabView and are logging their data to an SQL database, which was generated by TestStand.
I have written a program in c# and using Entity FrameWork 6 to retrieve data based on a couple of filters i.e. date and tester number.
I am finding that querys that require retrieving data from multiple tables are running very very slow.
Here is an example of a query
using (var db = new LoggingEntities())
{
db.Configuration.AutoDetectChangesEnabled = false;
db.Configuration.LazyLoadingEnabled = false;
db.Configuration.ProxyCreationEnabled = false;
db.Database.CommandTimeout = 5000;
var Results = db.UUT_RESULT.Include("STEP_RESULT")
.Include("STEP_RESULT.STEP_NUMERICLIMIT1") .Include("STEP_RESULT.STEP_NUMERICLIMIT1.STEP_NUMERICLIMIT2")
.Include("STEP_RESULT.PROP_RESULT")
.AsNoTracking()
.Where(x => x.STATION_ID == SelectedTester && x.START_DATE_TIME.Value >= StartFilterDate && x.START_DATE_TIME.Value <= endDate).ToList();
}
At the time of writing this, the above query has been running for 40 minutes. I estimate that in total, across all 5 tables, this is retrieving 336,000 rows.
If I run the above without the includes, the query is completed in a few seconds with 500 Rows retrieved.
Just some extra info.
SQL is running on SQLEXPRESS - Yes i know this is not great and we are planning to move this onto our SQL server.
All Primary keys in the tables are GUID data type and so are the Relational Columns.
So based on the above, is this expected? especially with SQLEXPRESS? or does anyone suspect something else is wrong?
Based on what I have to work wit, is there a better was to do this, performance wise?
EDIT: SQL Profiler Trace
exec sp_executesql N'SELECT
[Project4].[C1] AS [C1],
[Project4].[ID] AS [ID],
[Project4].[STATION_ID] AS [STATION_ID],
[Project4].[BATCH_SERIAL_NUMBER] AS [BATCH_SERIAL_NUMBER],
[Project4].[TEST_SOCKET_INDEX] AS [TEST_SOCKET_INDEX],
[Project4].[UUT_SERIAL_NUMBER] AS [UUT_SERIAL_NUMBER],
[Project4].[USER_LOGIN_NAME] AS [USER_LOGIN_NAME],
[Project4].[START_DATE_TIME] AS [START_DATE_TIME],
[Project4].[EXECUTION_TIME] AS [EXECUTION_TIME],
[Project4].[UUT_STATUS] AS [UUT_STATUS],
[Project4].[UUT_ERROR_CODE] AS [UUT_ERROR_CODE],
[Project4].[UUT_ERROR_MESSAGE] AS [UUT_ERROR_MESSAGE],
[Project4].[PART_NUMBER] AS [PART_NUMBER],
[Project4].[TSR_FILE_NAME] AS [TSR_FILE_NAME],
[Project4].[TSR_FILE_ID] AS [TSR_FILE_ID],
[Project4].[TSR_FILE_CLOSED] AS [TSR_FILE_CLOSED],
[Project4].[StationType] AS [StationType],
[Project4].[C57] AS [C2],
[Project4].[C3] AS [C3],
[Project4].[C4] AS [C4],
[Project4].[C5] AS [C5],
[Project4].[C6] AS [C6],
[Project4].[C7] AS [C7],
[Project4].[C8] AS [C8],
[Project4].[C9] AS [C9],
[Project4].[C10] AS [C10],
[Project4].[C11] AS [C11],
[Project4].[C12] AS [C12],
[Project4].[C13] AS [C13],
[Project4].[C14] AS [C14],
[Project4].[C15] AS [C15],
[Project4].[C16] AS [C16],
[Project4].[C17] AS [C17],
[Project4].[C18] AS [C18],
[Project4].[C19] AS [C19],
[Project4].[C20] AS [C20],
[Project4].[C21] AS [C21],
[Project4].[C22] AS [C22],
[Project4].[C23] AS [C23],
[Project4].[C24] AS [C24],
[Project4].[C25] AS [C25],
[Project4].[C2] AS [C26],
[Project4].[C26] AS [C27],
[Project4].[C27] AS [C28],
[Project4].[C28] AS [C29],
[Project4].[C29] AS [C30],
[Project4].[C30] AS [C31],
[Project4].[C31] AS [C32],
[Project4].[C32] AS [C33],
[Project4].[C33] AS [C34],
[Project4].[C34] AS [C35],
[Project4].[C35] AS [C36],
[Project4].[C36] AS [C37],
[Project4].[C37] AS [C38],
[Project4].[C38] AS [C39],
[Project4].[C39] AS [C40],
[Project4].[C40] AS [C41],
[Project4].[C41] AS [C42],
[Project4].[C42] AS [C43],
[Project4].[C43] AS [C44],
[Project4].[C44] AS [C45],
[Project4].[C45] AS [C46],
[Project4].[C46] AS [C47],
[Project4].[C47] AS [C48],
[Project4].[C48] AS [C49],
[Project4].[C49] AS [C50],
[Project4].[C50] AS [C51],
[Project4].[C51] AS [C52],
[Project4].[C52] AS [C53],
[Project4].[C53] AS [C54],
[Project4].[C54] AS [C55],
[Project4].[C55] AS [C56],
[Project4].[C56] AS [C57]
FROM ( SELECT
[Project1].[ID] AS [ID],
[Project1].[STATION_ID] AS [STATION_ID],
[Project1].[BATCH_SERIAL_NUMBER] AS [BATCH_SERIAL_NUMBER],
[Project1].[TEST_SOCKET_INDEX] AS [TEST_SOCKET_INDEX],
[Project1].[UUT_SERIAL_NUMBER] AS [UUT_SERIAL_NUMBER],
[Project1].[USER_LOGIN_NAME] AS [USER_LOGIN_NAME],
[Project1].[START_DATE_TIME] AS [START_DATE_TIME],
[Project1].[EXECUTION_TIME] AS [EXECUTION_TIME],
[Project1].[UUT_STATUS] AS [UUT_STATUS],
[Project1].[UUT_ERROR_CODE] AS [UUT_ERROR_CODE],
[Project1].[UUT_ERROR_MESSAGE] AS [UUT_ERROR_MESSAGE],
[Project1].[PART_NUMBER] AS [PART_NUMBER],
[Project1].[TSR_FILE_NAME] AS [TSR_FILE_NAME],
[Project1].[TSR_FILE_ID] AS [TSR_FILE_ID],
[Project1].[TSR_FILE_CLOSED] AS [TSR_FILE_CLOSED],
[Project1].[StationType] AS [StationType],
[Project1].[C1] AS [C1],
[UnionAll1].[C1] AS [C2],
[UnionAll1].[C2] AS [C3],
[UnionAll1].[ID] AS [C4],
[UnionAll1].[UUT_RESULT] AS [C5],
[UnionAll1].[STEP_PARENT] AS [C6],
[UnionAll1].[ORDER_NUMBER] AS [C7],
[UnionAll1].[STEP_NAME] AS [C8],
[UnionAll1].[STEP_TYPE] AS [C9],
[UnionAll1].[STEP_GROUP] AS [C10],
[UnionAll1].[STEP_INDEX] AS [C11],
[UnionAll1].[STEP_ID] AS [C12],
[UnionAll1].[STATUS] AS [C13],
[UnionAll1].[REPORT_TEXT] AS [C14],
[UnionAll1].[ERROR_CODE] AS [C15],
[UnionAll1].[ERROR_MESSAGE] AS [C16],
[UnionAll1].[CAUSED_SEQFAIL] AS [C17],
[UnionAll1].[MODULE_TIME] AS [C18],
[UnionAll1].[TOTAL_TIME] AS [C19],
[UnionAll1].[NUM_LOOPS] AS [C20],
[UnionAll1].[NUM_PASSED] AS [C21],
[UnionAll1].[NUM_FAILED] AS [C22],
[UnionAll1].[ENDING_LOOP_INDEX] AS [C23],
[UnionAll1].[LOOP_INDEX] AS [C24],
[UnionAll1].[INTERACTIVE_EXENUM] AS [C25],
[UnionAll1].[C3] AS [C26],
[UnionAll1].[ID1] AS [C27],
[UnionAll1].[STEP_RESULT] AS [C28],
[UnionAll1].[PROP_PARENT] AS [C29],
[UnionAll1].[ORDER_NUMBER1] AS [C30],
[UnionAll1].[NAME] AS [C31],
[UnionAll1].[PATH] AS [C32],
[UnionAll1].[CATEGORY] AS [C33],
[UnionAll1].[TYPE_VALUE] AS [C34],
[UnionAll1].[TYPE_NAME] AS [C35],
[UnionAll1].[DISPLAY_FORMAT] AS [C36],
[UnionAll1].[DATA] AS [C37],
[UnionAll1].[C4] AS [C38],
[UnionAll1].[ID2] AS [C39],
[UnionAll1].[PROP_RESULT] AS [C40],
[UnionAll1].[COMP_OPERATOR] AS [C41],
[UnionAll1].[HIGH_LIMIT] AS [C42],
[UnionAll1].[LOW_LIMIT] AS [C43],
[UnionAll1].[UNITS] AS [C44],
[UnionAll1].[STATUS1] AS [C45],
[UnionAll1].[C5] AS [C46],
[UnionAll1].[C6] AS [C47],
[UnionAll1].[C7] AS [C48],
[UnionAll1].[C8] AS [C49],
[UnionAll1].[C9] AS [C50],
[UnionAll1].[C10] AS [C51],
[UnionAll1].[C11] AS [C52],
[UnionAll1].[C12] AS [C53],
[UnionAll1].[C13] AS [C54],
[UnionAll1].[C14] AS [C55],
[UnionAll1].[C15] AS [C56],
CASE WHEN ([UnionAll1].[ID] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C57]
FROM (SELECT
[Extent1].[ID] AS [ID],
[Extent1].[STATION_ID] AS [STATION_ID],
[Extent1].[BATCH_SERIAL_NUMBER] AS [BATCH_SERIAL_NUMBER],
[Extent1].[TEST_SOCKET_INDEX] AS [TEST_SOCKET_INDEX],
[Extent1].[UUT_SERIAL_NUMBER] AS [UUT_SERIAL_NUMBER],
[Extent1].[USER_LOGIN_NAME] AS [USER_LOGIN_NAME],
[Extent1].[START_DATE_TIME] AS [START_DATE_TIME],
[Extent1].[EXECUTION_TIME] AS [EXECUTION_TIME],
[Extent1].[UUT_STATUS] AS [UUT_STATUS],
[Extent1].[UUT_ERROR_CODE] AS [UUT_ERROR_CODE],
[Extent1].[UUT_ERROR_MESSAGE] AS [UUT_ERROR_MESSAGE],
[Extent1].[PART_NUMBER] AS [PART_NUMBER],
[Extent1].[TSR_FILE_NAME] AS [TSR_FILE_NAME],
[Extent1].[TSR_FILE_ID] AS [TSR_FILE_ID],
[Extent1].[TSR_FILE_CLOSED] AS [TSR_FILE_CLOSED],
[Extent1].[StationType] AS [StationType],
1 AS [C1]
FROM [dbo].[UUT_RESULT] AS [Extent1]
WHERE (([Extent1].[STATION_ID] = #p__linq__0) OR (([Extent1].[STATION_ID] IS NULL) AND (#p__linq__0 IS NULL))) AND ([Extent1].[START_DATE_TIME] >= #p__linq__1) AND ([Extent1].[START_DATE_TIME] <= #p__linq__2) ) AS [Project1]
OUTER APPLY (SELECT
CASE WHEN ([Join1].[ID1] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1],
1 AS [C2],
[Extent2].[ID] AS [ID],
[Extent2].[UUT_RESULT] AS [UUT_RESULT],
[Extent2].[STEP_PARENT] AS [STEP_PARENT],
[Extent2].[ORDER_NUMBER] AS [ORDER_NUMBER],
[Extent2].[STEP_NAME] AS [STEP_NAME],
[Extent2].[STEP_TYPE] AS [STEP_TYPE],
[Extent2].[STEP_GROUP] AS [STEP_GROUP],
[Extent2].[STEP_INDEX] AS [STEP_INDEX],
[Extent2].[STEP_ID] AS [STEP_ID],
[Extent2].[STATUS] AS [STATUS],
[Extent2].[REPORT_TEXT] AS [REPORT_TEXT],
[Extent2].[ERROR_CODE] AS [ERROR_CODE],
[Extent2].[ERROR_MESSAGE] AS [ERROR_MESSAGE],
[Extent2].[CAUSED_SEQFAIL] AS [CAUSED_SEQFAIL],
[Extent2].[MODULE_TIME] AS [MODULE_TIME],
[Extent2].[TOTAL_TIME] AS [TOTAL_TIME],
[Extent2].[NUM_LOOPS] AS [NUM_LOOPS],
[Extent2].[NUM_PASSED] AS [NUM_PASSED],
[Extent2].[NUM_FAILED] AS [NUM_FAILED],
[Extent2].[ENDING_LOOP_INDEX] AS [ENDING_LOOP_INDEX],
[Extent2].[LOOP_INDEX] AS [LOOP_INDEX],
[Extent2].[INTERACTIVE_EXENUM] AS [INTERACTIVE_EXENUM],
CASE WHEN ([Join1].[ID1] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C3],
[Join1].[ID1] AS [ID1],
[Join1].[STEP_RESULT] AS [STEP_RESULT],
[Join1].[PROP_PARENT] AS [PROP_PARENT],
[Join1].[ORDER_NUMBER] AS [ORDER_NUMBER1],
[Join1].[NAME] AS [NAME],
[Join1].[PATH] AS [PATH],
[Join1].[CATEGORY] AS [CATEGORY],
[Join1].[TYPE_VALUE] AS [TYPE_VALUE],
[Join1].[TYPE_NAME] AS [TYPE_NAME],
[Join1].[DISPLAY_FORMAT] AS [DISPLAY_FORMAT],
[Join1].[DATA] AS [DATA],
CASE WHEN ([Join1].[ID1] IS NULL) THEN CAST(NULL AS int) WHEN ([Join1].[ID2] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C4],
[Join1].[ID2] AS [ID2],
[Join1].[PROP_RESULT] AS [PROP_RESULT],
[Join1].[COMP_OPERATOR] AS [COMP_OPERATOR],
[Join1].[HIGH_LIMIT] AS [HIGH_LIMIT],
[Join1].[LOW_LIMIT] AS [LOW_LIMIT],
[Join1].[UNITS] AS [UNITS],
[Join1].[STATUS] AS [STATUS1],
CAST(NULL AS uniqueidentifier) AS [C5],
CAST(NULL AS uniqueidentifier) AS [C6],
CAST(NULL AS uniqueidentifier) AS [C7],
CAST(NULL AS int) AS [C8],
CAST(NULL AS varchar(1)) AS [C9],
CAST(NULL AS varchar(1)) AS [C10],
CAST(NULL AS int) AS [C11],
CAST(NULL AS int) AS [C12],
CAST(NULL AS varchar(1)) AS [C13],
CAST(NULL AS varchar(1)) AS [C14],
CAST(NULL AS varchar(1)) AS [C15]
FROM [dbo].[STEP_RESULT] AS [Extent2]
LEFT OUTER JOIN (SELECT [Extent3].[ID] AS [ID1], [Extent3].[STEP_RESULT] AS [STEP_RESULT], [Extent3].[PROP_PARENT] AS [PROP_PARENT], [Extent3].[ORDER_NUMBER] AS [ORDER_NUMBER], [Extent3].[NAME] AS [NAME], [Extent3].[PATH] AS [PATH], [Extent3].[CATEGORY] AS [CATEGORY], [Extent3].[TYPE_VALUE] AS [TYPE_VALUE], [Extent3].[TYPE_NAME] AS [TYPE_NAME], [Extent3].[DISPLAY_FORMAT] AS [DISPLAY_FORMAT], [Extent3].[DATA] AS [DATA], [Extent4].[ID] AS [ID2], [Extent4].[PROP_RESULT] AS [PROP_RESULT], [Extent4].[COMP_OPERATOR] AS [COMP_OPERATOR], [Extent4].[HIGH_LIMIT] AS [HIGH_LIMIT], [Extent4].[LOW_LIMIT] AS [LOW_LIMIT], [Extent4].[UNITS] AS [UNITS], [Extent4].[STATUS] AS [STATUS]
FROM [dbo].[STEP_NUMERICLIMIT1] AS [Extent3]
LEFT OUTER JOIN [dbo].[STEP_NUMERICLIMIT2] AS [Extent4] ON [Extent3].[ID] = [Extent4].[PROP_RESULT] ) AS [Join1] ON [Extent2].[ID] = [Join1].[STEP_RESULT]
WHERE [Project1].[ID] = [Extent2].[UUT_RESULT]
UNION ALL
SELECT
2 AS [C1],
2 AS [C2],
[Extent5].[ID] AS [ID],
[Extent5].[UUT_RESULT] AS [UUT_RESULT],
[Extent5].[STEP_PARENT] AS [STEP_PARENT],
[Extent5].[ORDER_NUMBER] AS [ORDER_NUMBER],
[Extent5].[STEP_NAME] AS [STEP_NAME],
[Extent5].[STEP_TYPE] AS [STEP_TYPE],
[Extent5].[STEP_GROUP] AS [STEP_GROUP],
[Extent5].[STEP_INDEX] AS [STEP_INDEX],
[Extent5].[STEP_ID] AS [STEP_ID],
[Extent5].[STATUS] AS [STATUS],
[Extent5].[REPORT_TEXT] AS [REPORT_TEXT],
[Extent5].[ERROR_CODE] AS [ERROR_CODE],
[Extent5].[ERROR_MESSAGE] AS [ERROR_MESSAGE],
[Extent5].[CAUSED_SEQFAIL] AS [CAUSED_SEQFAIL],
[Extent5].[MODULE_TIME] AS [MODULE_TIME],
[Extent5].[TOTAL_TIME] AS [TOTAL_TIME],
[Extent5].[NUM_LOOPS] AS [NUM_LOOPS],
[Extent5].[NUM_PASSED] AS [NUM_PASSED],
[Extent5].[NUM_FAILED] AS [NUM_FAILED],
[Extent5].[ENDING_LOOP_INDEX] AS [ENDING_LOOP_INDEX],
[Extent5].[LOOP_INDEX] AS [LOOP_INDEX],
[Extent5].[INTERACTIVE_EXENUM] AS [INTERACTIVE_EXENUM],
CAST(NULL AS int) AS [C3],
CAST(NULL AS uniqueidentifier) AS [C4],
CAST(NULL AS uniqueidentifier) AS [C5],
CAST(NULL AS uniqueidentifier) AS [C6],
CAST(NULL AS int) AS [C7],
CAST(NULL AS varchar(1)) AS [C8],
CAST(NULL AS varchar(1)) AS [C9],
CAST(NULL AS int) AS [C10],
CAST(NULL AS int) AS [C11],
CAST(NULL AS varchar(1)) AS [C12],
CAST(NULL AS varchar(1)) AS [C13],
CAST(NULL AS float) AS [C14],
CAST(NULL AS int) AS [C15],
CAST(NULL AS uniqueidentifier) AS [C16],
CAST(NULL AS uniqueidentifier) AS [C17],
CAST(NULL AS varchar(1)) AS [C18],
CAST(NULL AS float) AS [C19],
CAST(NULL AS float) AS [C20],
CAST(NULL AS varchar(1)) AS [C21],
CAST(NULL AS varchar(1)) AS [C22],
[Extent6].[ID] AS [ID1],
[Extent6].[STEP_RESULT] AS [STEP_RESULT],
[Extent6].[PROP_PARENT] AS [PROP_PARENT],
[Extent6].[ORDER_NUMBER] AS [ORDER_NUMBER1],
[Extent6].[NAME] AS [NAME],
[Extent6].[PATH] AS [PATH],
[Extent6].[CATEGORY] AS [CATEGORY],
[Extent6].[TYPE_VALUE] AS [TYPE_VALUE],
[Extent6].[TYPE_NAME] AS [TYPE_NAME],
[Extent6].[DISPLAY_FORMAT] AS [DISPLAY_FORMAT],
[Extent6].[DATA] AS [DATA]
FROM [dbo].[STEP_RESULT] AS [Extent5]
INNER JOIN [dbo].[PROP_RESULT] AS [Extent6] ON [Extent5].[ID] = [Extent6].[STEP_RESULT]
WHERE [Project1].[ID] = [Extent5].[UUT_RESULT]) AS [UnionAll1]
) AS [Project4]
ORDER BY [Project4].[ID] ASC, [Project4].[C57] ASC, [Project4].[C4] ASC, [Project4].[C2] ASC, [Project4].[C27] ASC, [Project4].[C38] ASC',N'#p__linq__0 varchar(8000),#p__linq__1 datetime2(7),#p__linq__2 datetime2(7)',#p__linq__0='SIDEPCBA',#p__linq__1='2017-08-03 00:00:00',#p__linq__2='2017-08-03 23:59:00'
If you haven't already done it - check what indexes that could/should be created for your specific query. The deault NI SQL database is not indexed or optimized in any way. Run your slow query - and then this query to check what could be done.
-- check what could be indexed
SELECT mig.*, statement AS table_name,
column_id, column_name, column_usage
FROM sys.dm_db_missing_index_details AS mid
CROSS APPLY sys.dm_db_missing_index_columns (mid.index_handle)
INNER JOIN sys.dm_db_missing_index_groups AS mig ON mig.index_handle = mid.index_handle
ORDER BY mig.index_group_handle, mig.index_handle, column_id;
I'm using ASP.Net MVC 5 and I'm calling this line all over my code
string userId = User.Identity.GetUserId();
Does ASP.NET MVC go and fetch this from the table for each call, or does it get cached?
Looking at the decompiled sources of Microsoft.AspNet.Identity.Core.dll, you can see that it retrieves the user id from the claims of the current identity. So it doesn't fetch this info from the database.
public static string GetUserId(this IIdentity identity)
{
if (identity == null)
throw new ArgumentNullException("identity");
ClaimsIdentity identity1 = identity as ClaimsIdentity;
if (identity1 != null)
return IdentityExtensions.FindFirstValue(identity1, "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier");
return (string) null;
}
It seems that the id along with the username are cached when you login.
I've used SQL Server Profiler and after logged in running User.Identity.GetUserId(); the identity system made no queries to the database.
This is the query made on loggin:
exec sp_executesql N'SELECT
[UnionAll2].[C2] AS [C1],
[UnionAll2].[C3] AS [C2],
[UnionAll2].[C4] AS [C3],
[UnionAll2].[C5] AS [C4],
[UnionAll2].[C6] AS [C5],
[UnionAll2].[C7] AS [C6],
[UnionAll2].[C8] AS [C7],
[UnionAll2].[C9] AS [C8],
[UnionAll2].[C10] AS [C9],
[UnionAll2].[C11] AS [C10],
[UnionAll2].[C12] AS [C11],
[UnionAll2].[C13] AS [C12],
[UnionAll2].[C14] AS [C13],
[UnionAll2].[C1] AS [C14],
[UnionAll2].[C15] AS [C15],
[UnionAll2].[C16] AS [C16],
[UnionAll2].[C17] AS [C17],
[UnionAll2].[C18] AS [C18],
[UnionAll2].[C19] AS [C19],
[UnionAll2].[C20] AS [C20],
[UnionAll2].[C21] AS [C21],
[UnionAll2].[C22] AS [C22],
[UnionAll2].[C23] AS [C23],
[UnionAll2].[C24] AS [C24],
[UnionAll2].[C25] AS [C25]
FROM (SELECT
[UnionAll1].[C1] AS [C1],
[UnionAll1].[AccessFailedCount] AS [C2],
[UnionAll1].[Id] AS [C3],
[UnionAll1].[Email] AS [C4],
[UnionAll1].[EmailConfirmed] AS [C5],
[UnionAll1].[PasswordHash] AS [C6],
[UnionAll1].[SecurityStamp] AS [C7],
[UnionAll1].[PhoneNumber] AS [C8],
[UnionAll1].[PhoneNumberConfirmed] AS [C9],
[UnionAll1].[TwoFactorEnabled] AS [C10],
[UnionAll1].[LockoutEndDateUtc] AS [C11],
[UnionAll1].[LockoutEnabled] AS [C12],
[UnionAll1].[AccessFailedCount1] AS [C13],
[UnionAll1].[UserName] AS [C14],
[UnionAll1].[UserId] AS [C15],
[UnionAll1].[RoleId] AS [C16],
[UnionAll1].[UserId1] AS [C17],
[UnionAll1].[C2] AS [C18],
[UnionAll1].[C3] AS [C19],
[UnionAll1].[C4] AS [C20],
[UnionAll1].[C5] AS [C21],
[UnionAll1].[C6] AS [C22],
[UnionAll1].[C7] AS [C23],
[UnionAll1].[C8] AS [C24],
[UnionAll1].[C9] AS [C25]
FROM (SELECT
CASE WHEN ([Extent2].[UserId] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1],
[Limit1].[AccessFailedCount] AS [AccessFailedCount],
[Limit1].[Id] AS [Id],
[Limit1].[Email] AS [Email],
[Limit1].[EmailConfirmed] AS [EmailConfirmed],
[Limit1].[PasswordHash] AS [PasswordHash],
[Limit1].[SecurityStamp] AS [SecurityStamp],
[Limit1].[PhoneNumber] AS [PhoneNumber],
[Limit1].[PhoneNumberConfirmed] AS [PhoneNumberConfirmed],
[Limit1].[TwoFactorEnabled] AS [TwoFactorEnabled],
[Limit1].[LockoutEndDateUtc] AS [LockoutEndDateUtc],
[Limit1].[LockoutEnabled] AS [LockoutEnabled],
[Limit1].[AccessFailedCount] AS [AccessFailedCount1],
[Limit1].[UserName] AS [UserName],
[Extent2].[UserId] AS [UserId],
[Extent2].[RoleId] AS [RoleId],
[Extent2].[UserId] AS [UserId1],
CAST(NULL AS int) AS [C2],
CAST(NULL AS varchar(1)) AS [C3],
CAST(NULL AS varchar(1)) AS [C4],
CAST(NULL AS varchar(1)) AS [C5],
CAST(NULL AS varchar(1)) AS [C6],
CAST(NULL AS varchar(1)) AS [C7],
CAST(NULL AS varchar(1)) AS [C8],
CAST(NULL AS varchar(1)) AS [C9]
FROM (SELECT TOP (1)
[Extent1].[Id] AS [Id],
[Extent1].[Email] AS [Email],
[Extent1].[EmailConfirmed] AS [EmailConfirmed],
[Extent1].[PasswordHash] AS [PasswordHash],
[Extent1].[SecurityStamp] AS [SecurityStamp],
[Extent1].[PhoneNumber] AS [PhoneNumber],
[Extent1].[PhoneNumberConfirmed] AS [PhoneNumberConfirmed],
[Extent1].[TwoFactorEnabled] AS [TwoFactorEnabled],
[Extent1].[LockoutEndDateUtc] AS [LockoutEndDateUtc],
[Extent1].[LockoutEnabled] AS [LockoutEnabled],
[Extent1].[AccessFailedCount] AS [AccessFailedCount],
[Extent1].[UserName] AS [UserName]
FROM [dbo].[AspNetUsers] AS [Extent1]
WHERE [Extent1].[Id] = #p__linq__0 ) AS [Limit1]
LEFT OUTER JOIN [dbo].[AspNetUserRoles] AS [Extent2] ON [Limit1].[Id] = [Extent2].[UserId]
UNION ALL
SELECT
2 AS [C1],
[Limit2].[AccessFailedCount] AS [AccessFailedCount],
[Limit2].[Id] AS [Id],
[Limit2].[Email] AS [Email],
[Limit2].[EmailConfirmed] AS [EmailConfirmed],
[Limit2].[PasswordHash] AS [PasswordHash],
[Limit2].[SecurityStamp] AS [SecurityStamp],
[Limit2].[PhoneNumber] AS [PhoneNumber],
[Limit2].[PhoneNumberConfirmed] AS [PhoneNumberConfirmed],
[Limit2].[TwoFactorEnabled] AS [TwoFactorEnabled],
[Limit2].[LockoutEndDateUtc] AS [LockoutEndDateUtc],
[Limit2].[LockoutEnabled] AS [LockoutEnabled],
[Limit2].[AccessFailedCount] AS [AccessFailedCount1],
[Limit2].[UserName] AS [UserName],
CAST(NULL AS varchar(1)) AS [C2],
CAST(NULL AS varchar(1)) AS [C3],
CAST(NULL AS varchar(1)) AS [C4],
[Extent4].[Id] AS [Id1],
[Extent4].[UserId] AS [UserId],
[Extent4].[ClaimType] AS [ClaimType],
[Extent4].[ClaimValue] AS [ClaimValue],
CAST(NULL AS varchar(1)) AS [C5],
CAST(NULL AS varchar(1)) AS [C6],
CAST(NULL AS varchar(1)) AS [C7],
CAST(NULL AS varchar(1)) AS [C8]
FROM (SELECT TOP (1)
[Extent3].[Id] AS [Id],
[Extent3].[Email] AS [Email],
[Extent3].[EmailConfirmed] AS [EmailConfirmed],
[Extent3].[PasswordHash] AS [PasswordHash],
[Extent3].[SecurityStamp] AS [SecurityStamp],
[Extent3].[PhoneNumber] AS [PhoneNumber],
[Extent3].[PhoneNumberConfirmed] AS [PhoneNumberConfirmed],
[Extent3].[TwoFactorEnabled] AS [TwoFactorEnabled],
[Extent3].[LockoutEndDateUtc] AS [LockoutEndDateUtc],
[Extent3].[LockoutEnabled] AS [LockoutEnabled],
[Extent3].[AccessFailedCount] AS [AccessFailedCount],
[Extent3].[UserName] AS [UserName]
FROM [dbo].[AspNetUsers] AS [Extent3]
WHERE [Extent3].[Id] = #p__linq__0 ) AS [Limit2]
INNER JOIN [dbo].[AspNetUserClaims] AS [Extent4] ON [Limit2].[Id] = [Extent4].[UserId]) AS [UnionAll1]
UNION ALL
SELECT
3 AS [C1],
[Limit3].[AccessFailedCount] AS [AccessFailedCount],
[Limit3].[Id] AS [Id],
[Limit3].[Email] AS [Email],
[Limit3].[EmailConfirmed] AS [EmailConfirmed],
[Limit3].[PasswordHash] AS [PasswordHash],
[Limit3].[SecurityStamp] AS [SecurityStamp],
[Limit3].[PhoneNumber] AS [PhoneNumber],
[Limit3].[PhoneNumberConfirmed] AS [PhoneNumberConfirmed],
[Limit3].[TwoFactorEnabled] AS [TwoFactorEnabled],
[Limit3].[LockoutEndDateUtc] AS [LockoutEndDateUtc],
[Limit3].[LockoutEnabled] AS [LockoutEnabled],
[Limit3].[AccessFailedCount] AS [AccessFailedCount1],
[Limit3].[UserName] AS [UserName],
CAST(NULL AS varchar(1)) AS [C2],
CAST(NULL AS varchar(1)) AS [C3],
CAST(NULL AS varchar(1)) AS [C4],
CAST(NULL AS int) AS [C5],
CAST(NULL AS varchar(1)) AS [C6],
CAST(NULL AS varchar(1)) AS [C7],
CAST(NULL AS varchar(1)) AS [C8],
[Extent6].[LoginProvider] AS [LoginProvider],
[Extent6].[ProviderKey] AS [ProviderKey],
[Extent6].[UserId] AS [UserId],
[Extent6].[UserId] AS [UserId1]
FROM (SELECT TOP (1)
[Extent5].[Id] AS [Id],
[Extent5].[Email] AS [Email],
[Extent5].[EmailConfirmed] AS [EmailConfirmed],
[Extent5].[PasswordHash] AS [PasswordHash],
[Extent5].[SecurityStamp] AS [SecurityStamp],
[Extent5].[PhoneNumber] AS [PhoneNumber],
[Extent5].[PhoneNumberConfirmed] AS [PhoneNumberConfirmed],
[Extent5].[TwoFactorEnabled] AS [TwoFactorEnabled],
[Extent5].[LockoutEndDateUtc] AS [LockoutEndDateUtc],
[Extent5].[LockoutEnabled] AS [LockoutEnabled],
[Extent5].[AccessFailedCount] AS [AccessFailedCount],
[Extent5].[UserName] AS [UserName]
FROM [dbo].[AspNetUsers] AS [Extent5]
WHERE [Extent5].[Id] = #p__linq__0 ) AS [Limit3]
INNER JOIN [dbo].[AspNetUserLogins] AS [Extent6] ON [Limit3].[Id] = [Extent6].[UserId]) AS [UnionAll2]
ORDER BY [UnionAll2].[C3] ASC, [UnionAll2].[C1] ASC',N'#p__linq__0 nvarchar(4000)',#p__linq__0=N'b73f9738-76ed-48d5-a8fd-cbf23a233fe9'
I know it's ain't gonna be easy but I'm stuck on this and can't move on.
I have this linq
var resourceItems = queryable
.Select(ri => new ResourceItemDto
{
Id = ri.Id,
CreationDate = ri.CreationDate,
ParentId = ri.FolderId,
Name = ri.Name,
Type = ri.ResourceType,
Url = ri.Url,
Size = ri.Size,
MediaAssetUuid = ri.MediaAssetUuid,
Blob = ri.Blob,
Container = ri.Container,
GroupId = ri.GroupId,
Status = (ResourceItemStatus) ri.Status,
Progress =
ri.EncodingJobs.SelectMany(j => j.EncodingTasks).Any()
? (ri.EncodingJobs.SelectMany(j => j.EncodingTasks).Sum(t => (decimal?) t.Progress)/
ri.EncodingJobs.SelectMany(j => j.EncodingTasks).Count() ?? 0M)
: 0M,
Uuid = ri.Uuid,
CreatedBy =
new UserDto
{
Id = ri.User.Id,
UserName = ri.User.UserName,
FirstName = ri.User.FirstName,
LastName = ri.User.LastName
}
});
And now the task is to move this into a SP and I don't want to take the sql generated by the EF, it's clumsy and machine-generated.
I ended up having this:
SELECT
ri.Id
,ri.CreationDate
,ri.FolderId
,ri.Name
,ri.ResourceType
,ri.Url
,ri.Size
,ri.MediaAssetUuid
,ri.Blob
,ri.Container
,ri.GroupId
--, (sql_expression) AS Progress
,ri.Uuid
,u.Id AS UserId
,u.UserName
,u.FirstName
,u.LastName
FROM ResourceItem ri
INNER JOIN ResourceItemsTree rit ON ri.FolderId = rit.Id
INNER JOIN [User] u ON u.Id = ri.CreatedBy
WHERE
ri.IsDeleted = CAST(0 as BIT)
Now my problem is that Progress column calculation which includes a few repeating SelectMany statements and I don't know how to do with this.
Any help is really appreciated, guys.
There's a EncodingJobs table having a FK ResourceItemId (0 to many) to the resourceItem table, and there's another table EncodingTask with a FK EncodingJobId (the same 0 to many).
This is what EF generates:
SELECT
[Project4].[Id] AS [Id],
[Project4].[CreationDate] AS [CreationDate],
[Project4].[FolderId] AS [FolderId],
[Project4].[Name] AS [Name],
[Project4].[ResourceType] AS [ResourceType],
[Project4].[Url] AS [Url],
[Project4].[Size] AS [Size],
[Project4].[MediaAssetUuid] AS [MediaAssetUuid],
[Project4].[Blob] AS [Blob],
[Project4].[Container] AS [Container],
[Project4].[GroupId] AS [GroupId],
[Project4].[Status] AS [Status],
CASE WHEN ( EXISTS (SELECT
1 AS [C1]
FROM [dbo].[EncodingJob] AS [Extent12]
INNER JOIN [dbo].[EncodingTask] AS [Extent13] ON [Extent12].[Id] = [Extent13].[JobId]
WHERE [Project4].[Id] = [Extent12].[ResourceItemId]
)) THEN CASE WHEN ([Project4].[C1] / CAST( [Project4].[C2] AS decimal(19,0)) IS NULL) THEN cast(0 as decimal(18)) ELSE [Project4].[C3] / CAST( [Project4].[C4] AS decimal(19,0)) END ELSE cast(0 as decimal(18)) END AS [C1],
[Project4].[Uuid] AS [Uuid],
[Project4].[CreatedBy] AS [CreatedBy],
[Project4].[UserName] AS [UserName],
[Project4].[FirstName] AS [FirstName],
[Project4].[LastName] AS [LastName]
FROM ( SELECT
[Project3].[Id] AS [Id],
[Project3].[FolderId] AS [FolderId],
[Project3].[Name] AS [Name],
[Project3].[ResourceType] AS [ResourceType],
[Project3].[Url] AS [Url],
[Project3].[Size] AS [Size],
[Project3].[MediaAssetUuid] AS [MediaAssetUuid],
[Project3].[Status] AS [Status],
[Project3].[CreationDate] AS [CreationDate],
[Project3].[GroupId] AS [GroupId],
[Project3].[Container] AS [Container],
[Project3].[Blob] AS [Blob],
[Project3].[Uuid] AS [Uuid],
[Project3].[CreatedBy] AS [CreatedBy],
[Project3].[UserName] AS [UserName],
[Project3].[FirstName] AS [FirstName],
[Project3].[LastName] AS [LastName],
[Project3].[C1] AS [C1],
[Project3].[C2] AS [C2],
[Project3].[C3] AS [C3],
(SELECT
COUNT(1) AS [A1]
FROM [dbo].[EncodingJob] AS [Extent10]
INNER JOIN [dbo].[EncodingTask] AS [Extent11] ON [Extent10].[Id] = [Extent11].[JobId]
WHERE [Project3].[Id] = [Extent10].[ResourceItemId]) AS [C4]
FROM ( SELECT
[Project2].[Id] AS [Id],
[Project2].[FolderId] AS [FolderId],
[Project2].[Name] AS [Name],
[Project2].[ResourceType] AS [ResourceType],
[Project2].[Url] AS [Url],
[Project2].[Size] AS [Size],
[Project2].[MediaAssetUuid] AS [MediaAssetUuid],
[Project2].[Status] AS [Status],
[Project2].[CreationDate] AS [CreationDate],
[Project2].[GroupId] AS [GroupId],
[Project2].[Container] AS [Container],
[Project2].[Blob] AS [Blob],
[Project2].[Uuid] AS [Uuid],
[Project2].[CreatedBy] AS [CreatedBy],
[Project2].[UserName] AS [UserName],
[Project2].[FirstName] AS [FirstName],
[Project2].[LastName] AS [LastName],
[Project2].[C1] AS [C1],
[Project2].[C2] AS [C2],
(SELECT
SUM([Extent9].[Progress]) AS [A1]
FROM [dbo].[EncodingJob] AS [Extent8]
INNER JOIN [dbo].[EncodingTask] AS [Extent9] ON [Extent8].[Id] = [Extent9].[JobId]
WHERE [Project2].[Id] = [Extent8].[ResourceItemId]) AS [C3]
FROM ( SELECT
[Project1].[Id] AS [Id],
[Project1].[FolderId] AS [FolderId],
[Project1].[Name] AS [Name],
[Project1].[ResourceType] AS [ResourceType],
[Project1].[Url] AS [Url],
[Project1].[Size] AS [Size],
[Project1].[MediaAssetUuid] AS [MediaAssetUuid],
[Project1].[Status] AS [Status],
[Project1].[CreationDate] AS [CreationDate],
[Project1].[GroupId] AS [GroupId],
[Project1].[Container] AS [Container],
[Project1].[Blob] AS [Blob],
[Project1].[Uuid] AS [Uuid],
[Project1].[CreatedBy] AS [CreatedBy],
[Project1].[UserName] AS [UserName],
[Project1].[FirstName] AS [FirstName],
[Project1].[LastName] AS [LastName],
[Project1].[C1] AS [C1],
(SELECT
COUNT(1) AS [A1]
FROM [dbo].[EncodingJob] AS [Extent6]
INNER JOIN [dbo].[EncodingTask] AS [Extent7] ON [Extent6].[Id] = [Extent7].[JobId]
WHERE [Project1].[Id] = [Extent6].[ResourceItemId]) AS [C2]
FROM ( SELECT
[Extent1].[Id] AS [Id],
[Extent1].[FolderId] AS [FolderId],
[Extent1].[Name] AS [Name],
[Extent1].[ResourceType] AS [ResourceType],
[Extent1].[Url] AS [Url],
[Extent1].[Size] AS [Size],
[Extent1].[MediaAssetUuid] AS [MediaAssetUuid],
[Extent1].[Status] AS [Status],
[Extent1].[CreationDate] AS [CreationDate],
[Extent1].[GroupId] AS [GroupId],
[Extent1].[Container] AS [Container],
[Extent1].[Blob] AS [Blob],
[Extent1].[Uuid] AS [Uuid],
[Extent1].[CreatedBy] AS [CreatedBy],
[Extent2].[UserName] AS [UserName],
[Extent3].[FirstName] AS [FirstName],
[Extent3].[LastName] AS [LastName],
(SELECT
SUM([Extent5].[Progress]) AS [A1]
FROM [dbo].[EncodingJob] AS [Extent4]
INNER JOIN [dbo].[EncodingTask] AS [Extent5] ON [Extent4].[Id] = [Extent5].[JobId]
WHERE [Extent1].[Id] = [Extent4].[ResourceItemId]) AS [C1]
FROM [dbo].[ResourceItem] AS [Extent1]
INNER JOIN [dbo].[User] AS [Extent2] ON [Extent1].[CreatedBy] = [Extent2].[Id]
LEFT OUTER JOIN [dbo].[User] AS [Extent3] ON [Extent1].[CreatedBy] = [Extent3].[Id]
WHERE ([Extent1].[IsDeleted] <> cast(1 as bit)) AND ([Extent1].[FolderId] = #p__linq__0)
) AS [Project1]
) AS [Project2]
) AS [Project3]
) AS [Project4]
you just need to think what you are looking for.
In this case its the total of the progress / count, grouped per resourceItem.
The following should be about right, but the IDs might need correcting!
This uses a common table expression (SQL Server) but could easily be rewritten to a subquery
;WITH prog AS
(
SELECT
ej.ResourceItemId,
SUM(et.Progress) / COUNT(*) AS totalProg
FROM EncodingJobs ej
JOIN EncodingTasks et ON ej.Id = et.EncodingJobId
GROUP BY
ej.ResourceItemId
)
SELECT
ri.Id
,ri.CreationDate
,ri.FolderId
,ri.Name
,ri.ResourceType
,ri.Url
,ri.Size
,ri.MediaAssetUuid
,ri.Blob
,ri.Container
,ri.GroupId
,ISNULL(prog.totalProg, 0) AS Progress
,ri.Uuid
,u.Id AS UserId
,u.UserName
,u.FirstName
,u.LastName
FROM ResourceItem ri
INNER JOIN ResourceItemsTree rit ON ri.FolderId = rit.Id
INNER JOIN [User] u ON u.Id = ri.CreatedBy
LEFT JOIN prog ON ri.Id = prog.ResourceItemId
WHERE
ri.IsDeleted = CAST(0 as BIT)
Well this should be something like that.
Cast the count to decimal if Progress is an integer, to avoid integer division.If not, you can avoid the cast
SELECT
ri.Id
,ri.CreationDate
,ri.FolderId
,ri.Name
,ri.ResourceType
,ri.Url
,ri.Size
,ri.MediaAssetUuid
,ri.Blob
,ri.Container
,ri.GroupId
coalesce(sum(et.Progress) / cast(count(*) as decimal(18,2)), 0) AS Progress
,ri.Uuid
,u.Id AS UserId
,u.UserName
,u.FirstName
,u.LastName
FROM ResourceItem ri
INNER JOIN ResourceItemsTree rit ON ri.FolderId = rit.Id
INNER JOIN [User] u ON u.Id = ri.CreatedBy
LEFT JOIN EncodingJob ej on ej.ResourceItemId= ri.Id
LEFT JOIN EncodingTask et on et.JobId = ej.Id
WHERE
ri.IsDeleted = 0
group by
ri.Id
,ri.CreationDate
,ri.FolderId
,ri.Name
,ri.ResourceType
,ri.Url
,ri.Size
,ri.MediaAssetUuid
,ri.Blob
,ri.Container
,ri.GroupId
,ri.Uuid
,u.Id AS UserId
,u.UserName
,u.FirstName
,u.LastName
You can attach SQL Server Profiler to my database and run the application. SQL Server Profiler will capture the SQL that is being run on the database. You can then use that SQL as a starting point for your stored procedure.
SQL Server Profiler Tutorial
I'm having trouble constructing an efficient query in EF4 using type per table (TPT) inheritance.
I have an entity called Episode, and each episode can have multiple events. There several different type of events all deriving from a base entity called Event. I want to filter on all episodes that don't contain a certain type of event. Episode has a navigation property that is a collection of all its events (i.e. a collection of the base Event type)
I've tried:
from episode in context.EpisodeSet
where episode.Events.OfType<DerivedEvent>().Count() == 0
select episode
and
from episode in context.EpisodeSet
where episode.Events.Where(p => p is DerivedEvent).Count() == 0
select episode
Both of these produce a typical long SQL expansion that queries every Event type table.
Shouldn't there be a way to express this query in LINQ that just involves a join between the Episode and the DerivedEvent table in the resulting SQL?
Edit:
In response to ProfessorX here is the generated SQL (basically just a typical massive union across all event tables)
SELECT
[Extent1].[Id] AS [Id],
[Extent1].[TypeId] AS [TypeId],
[Extent1].[PatientId] AS [PatientId],
[Extent1].[CentreId] AS [CentreId],
[Extent1].[CreatedOn] AS [CreatedOn],
[Extent1].[UpdatedOn] AS [UpdatedOn],
[Extent1].[CreatedBy] AS [CreatedBy],
[Extent1].[UpdatedBy] AS [UpdatedBy]
FROM [dbo].[Episode] AS [Extent1]
WHERE EXISTS (SELECT
1 AS [C1]
FROM [dbo].[Event] AS [Extent2]
LEFT OUTER JOIN (SELECT
[Extent3].[Id] AS [Id],
cast(1 as bit) AS [C1]
FROM [dbo].[InvasiveDischargableEvent] AS [Extent3] ) AS [Project1] ON [Extent2].[Id] = [Project1].[Id]
LEFT OUTER JOIN (SELECT
[UnionAll4].[C1] AS [C1],
[UnionAll4].[C2] AS [C2],
[UnionAll4].[C3] AS [C3],
[UnionAll4].[C4] AS [C4],
[UnionAll4].[C5] AS [C5],
[UnionAll4].[C6] AS [C6],
[UnionAll4].[C7] AS [C7]
FROM (SELECT
[UnionAll3].[C1] AS [C1],
[UnionAll3].[C2] AS [C2],
[UnionAll3].[C3] AS [C3],
[UnionAll3].[C4] AS [C4],
[UnionAll3].[C5] AS [C5],
[UnionAll3].[C6] AS [C6],
[UnionAll3].[C7] AS [C7]
FROM (SELECT
[UnionAll2].[C1] AS [C1],
[UnionAll2].[C2] AS [C2],
[UnionAll2].[C3] AS [C3],
[UnionAll2].[C4] AS [C4],
[UnionAll2].[C5] AS [C5],
[UnionAll2].[C6] AS [C6],
[UnionAll2].[C7] AS [C7]
FROM (SELECT
[UnionAll1].[Id] AS [C1],
[UnionAll1].[C1] AS [C2],
[UnionAll1].[C2] AS [C3],
[UnionAll1].[C3] AS [C4],
[UnionAll1].[C4] AS [C5],
[UnionAll1].[C5] AS [C6],
[UnionAll1].[C6] AS [C7]
FROM (SELECT
[Extent4].[Id] AS [Id],
cast(0 as bit) AS [C1],
cast(1 as bit) AS [C2],
cast(0 as bit) AS [C3],
cast(0 as bit) AS [C4],
cast(0 as bit) AS [C5],
cast(0 as bit) AS [C6]
FROM [dbo].[InvasivePSQ10Event] AS [Extent4]
UNION ALL
SELECT
[Extent5].[Id] AS [Id],
cast(0 as bit) AS [C1],
cast(0 as bit) AS [C2],
cast(0 as bit) AS [C3],
cast(0 as bit) AS [C4],
cast(0 as bit) AS [C5],
cast(1 as bit) AS [C6]
FROM [dbo].[InvasivePostTreatmentEvent] AS [Extent5]) AS [UnionAll1]
UNION ALL
SELECT
[Extent6].[Id] AS [Id],
cast(0 as bit) AS [C1],
cast(0 as bit) AS [C2],
cast(1 as bit) AS [C3],
cast(0 as bit) AS [C4],
cast(0 as bit) AS [C5],
cast(0 as bit) AS [C6]
FROM [dbo].[InvasiveTreatmentEvent] AS [Extent6]) AS [UnionAll2]
UNION ALL
SELECT
[Extent7].[Id] AS [Id],
cast(0 as bit) AS [C1],
cast(0 as bit) AS [C2],
cast(0 as bit) AS [C3],
cast(0 as bit) AS [C4],
cast(1 as bit) AS [C5],
cast(0 as bit) AS [C6]
FROM [dbo].[InvasiveConsultationEvent] AS [Extent7]) AS [UnionAll3]
UNION ALL
SELECT
[Extent8].[Id] AS [Id],
cast(1 as bit) AS [C1],
cast(0 as bit) AS [C2],
cast(0 as bit) AS [C3],
cast(0 as bit) AS [C4],
cast(0 as bit) AS [C5],
cast(0 as bit) AS [C6]
FROM [dbo].[InvasiveMOXFQEvent] AS [Extent8]) AS [UnionAll4]
UNION ALL
SELECT
[Extent9].[Id] AS [Id],
cast(0 as bit) AS [C1],
cast(0 as bit) AS [C2],
cast(0 as bit) AS [C3],
cast(1 as bit) AS [C4],
cast(0 as bit) AS [C5],
cast(0 as bit) AS [C6]
FROM [dbo].[InvasiveReferralEvent] AS [Extent9]) AS [UnionAll5] ON [Extent2].[Id] = [UnionAll5].[C1]
WHERE ([Extent1].[Id] = [Extent2].[EpisodeId]) AND (CASE WHEN (( NOT (([UnionAll5].[C2] = 1) AND ([UnionAll5].[C2] IS NOT NULL))) AND ( NOT (([UnionAll5].[C3] = 1) AND ([UnionAll5].[C3] IS NOT NULL))) AND ( NOT (([UnionAll5].[C4] = 1) AND ([UnionAll5].[C4] IS NOT NULL))) AND ( NOT (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL))) AND ( NOT (([UnionAll5].[C5] = 1) AND ([UnionAll5].[C5] IS NOT NULL)))) THEN '2X' WHEN (([UnionAll5].[C5] = 1) AND ([UnionAll5].[C5] IS NOT NULL)) THEN '2X0X' WHEN (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL) AND ( NOT (([UnionAll5].[C6] = 1) AND ([UnionAll5].[C6] IS NOT NULL))) AND ( NOT (([UnionAll5].[C7] = 1) AND ([UnionAll5].[C7] IS NOT NULL)))) THEN '2X1X' WHEN (([UnionAll5].[C4] = 1) AND ([UnionAll5].[C4] IS NOT NULL)) THEN '2X2X' WHEN (([UnionAll5].[C2] = 1) AND ([UnionAll5].[C2] IS NOT NULL)) THEN '2X3X' WHEN (([UnionAll5].[C6] = 1) AND ([UnionAll5].[C6] IS NOT NULL)) THEN '2X1X0X' WHEN (([UnionAll5].[C7] = 1) AND ([UnionAll5].[C7] IS NOT NULL)) THEN '2X1X1X' ELSE '2X4X' END LIKE '2X4X%')
)
After much head scratching I've managed to get this to work:
var episodes = (from episode in context.EpisodeSet
join e in context.EventSet.OfType<DerivedEvent>() on episode.Id equals e.EpisodeId into outer
from o in outer.DefaultIfEmpty()
where o == null
select episode)
So rather than try to apply an OfType filter to the navigation property I've had to apply it to the ObjectSet and do an outer join. Seems that OfType and 'as' type filtering don't work against Navigation Properties.
This produces the episodes that don't have a corresponding event in the DerivedEvent table, and with the kind of SQL that you would write by hand.
The LINQ follows the way you'd naturally write the query with SQL. It's just too easy to get seduced by all these navigation properties that lead to nice looking LINQ but awful looking SQL.
.Any() is better than .Count()
From my prospective your query can be optimized to:
context.EpisodeSet
.Where(e => e.Events.Any(p => p is DerivedEvent))
.Select(e => e);