0

我有这样的结构:

public class Tag
{
        public int TagId { get; set; }
        public virtual ICollection<Vacancy> Vacancies { get; set; }
        // ...
}

public class Vacancy
{
        public int VacancyId { get; set; }
        public virtual ICollection<Tag> Tags { get; set; }
        // ...
}

这些实体通过 EF / Code First 方法映射到 MS SQL。

之后,我以某种方式从上下文(基于用户查询)中获取标签列表:

List<Tag> userSelectedTags = ...;

我想计算这些标签包含多少空缺:

int count = userSelectedTags.SelectMany(t => t.Vacancies).Count();

它工作正常,但似乎这个查询没有得到很好的优化。当我遇到探查器时,我得到了这个:

exec sp_executesql N'SELECT 
[Extent2].[VacancyId] AS [VacancyId], 
[Extent2].[Title] AS [Title], 
[Extent2].[Salary] AS [Salary], 

...props... etc...

FROM  [dbo].[VacancyTagVacancies] AS [Extent1]
INNER JOIN [dbo].[Vacancies] AS [Extent2] ON [Extent1].[Vacancy_VacancyId] = [Extent2].[VacancyId]
WHERE [Extent1].[VacancyTag_VacancyTagId] = @EntityKeyValue1',N'@EntityKeyValue1 int',@EntityKeyValue1=1

换句话说,它不使用 COUNT sql 关键字,而只是返回整个集合并在 SQL Server 之外进行计算。

如何优化 LINQ 查询以便在此处使用 COUNT 而不是全选?谢谢。

4

2 回答 2

1

userSelectedTags不是查询,这意味着t.Vacancies成为对客户端属性的引用,在枚举时会检索Vacancies该特定Tag. 然后Count在客户端运行。

您需要从服务器端开始:

int count = (
    from tag in context.Tags
    where userSelectedTags.Contains(tag)
    from v in tag.Vacancies
    select v).Count();

如果这还不起作用,您可能需要制作 auserSelectedTagIds而不是。userSelectedTags

于 2012-08-17T12:30:32.307 回答
0

一种方法是像这样直接执行 SQL:

string nativeSQLQuery = "SELECT count(*) FROM <tables join>";

var queryResult = ctx.ExecuteStoreQuery<int>(nativeSQLQuery);
于 2012-08-17T12:14:28.203 回答