LINQ多対多どこで

c# entity-framework-core linq

質問

EF7(コア)/ SQL対応の多対多LINQクエリを作成する方法

たとえば、多言語を話す友達がたくさんいるとします。特定の言語セットの友達をすべて見つけたいとします。

class Friend
{
    Guid Id { get; set; }
    ICollection<FriendLanguage> Languages { get; set; }
}

class Language
{
    Guid { get; set; }
    ICollection<FriendLanguage> Friends { get; set; }
}

class FriendLanguage
{
    Friend { get; set; }
    Language { get; set; }
}

IEnumerable<Guid>言語IDのセットがあるとすれば、それらの言語を話すすべての友達を取り戻したいです。

私はこれを試してみました...

friends
    .Include(o => o.Languages).ThenInclude(o => o.Language)
    .SelectMany(o => o.Languages).Select(o => o.Language.Id)
    .Intersect(languages);

...しかし、これはGuidの縮小されたセットを返すだけです...ここからどこへ行くべきか、あるいは私が正しい道を進んでいるとしても、完全にはわからない。

受け入れられた回答

私が正しく理解しているならば、あなたはリストからすべての言語を話す友達を得たいです。

あなたの要求を表現する最も自然なLINQクエリは次のようになります。

var friends = db.Friends
    .Include(o => o.Languages).ThenInclude(o => o.Language)
    .Where(o => languages.All(id => o.Languages.Any(fl => fl.Language.Id == id)));

残念ながらSQLには向いていません。実際、EF Coreは現在それをSQLに変換することができず、メモリ内のデータを読み込み、そこでフィルタリングを行います。

それで、あなたは代わりにこれを使うことができます:

var friends = db.Friends
    .Include(o => o.Languages).ThenInclude(o => o.Language)
    .Where(o => o.Languages.Count(fl => languages.Contains(fl.Language.Id)) == languages.Count);

これは次のようになります。

SELECT [o].[Id]
FROM [Friends] AS [o]
WHERE (
    SELECT COUNT(*)
    FROM [FriendLanguages] AS [fl]
    WHERE [fl].[LanguageId] IN ('6e64302f-24db-4717-a5fe-2cc61985ca3a', '2c216a63-1f6a-4fad-9105-d5f8ece3fa3c') AND ([o].[Id] = [fl].[FriendId])
) = @__languages_Count_1
ORDER BY [o].[Id]

もしあなたが本当にリストにある言語のどれかを話す友達がほしいのなら、 Whereはもっと簡単です。

.Where(o => o.Languages.Any(fl => languages.Contains(fl.Language.Id)))

SQLは次のとおりです。

SELECT [o].[Id]
FROM [Friends] AS [o]
WHERE EXISTS (
    SELECT 1
    FROM [FriendLanguages] AS [fl]
    WHERE [fl].[LanguageId] IN ('ed3f85a7-e122-45dd-b0af-2020052d55a7', '4819cb7d-ad43-41a0-a3a1-979b7abc6265') AND ([o].[Id] = [fl].[FriendId]))
ORDER BY [o].[Id]


Related

ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ