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/コードファーストアプローチを使用してMSSQLにマップされます。

その後、(ユーザークエリに基づいて)コンテキストからタグのリストを取得します。

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キーワードを使用せず、コレクション全体を返し、SQLServerの外部で計算します。

すべてを選択する代わりにここでCOUNTを使用するために、LINQクエリを最適化するにはどうすればよいですか?ありがとう。

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();

これがまだ機能しない場合は、代わりにを作成する必要があるかもしれません。userSelectedTagIdsuserSelectedTags

于 2012-08-17T12:30:32.307 に答える
0

1 つの方法は、次のように SQL を直接実行することです。

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

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