次のように、データベースに多対多の関係を設定しています。
User
-------
Id (PK, Identity)
First
Last
...various other fields
Skill
-------
Id (PK, Identity)
Description
UserSkill
-----------
UserId (PK, FK on User.Id)
SkillId (PK, FK On Skill.Id)
DbContext でこの LINQ クエリを実行すると、次のようになります。
from u in Users
from s in u.Skills
where s.Id == 5
select new
{
u.Id,
s.Description
})
生成された SQL には、私が望むすべての内部結合が含まれています。
SELECT
[Extent1].[UserId] AS [UserId],
[Extent2].[Description] AS [Description]
FROM [dbo].[UserSkill] AS [Extent1]
INNER JOIN [dbo].[Skill] AS [Extent2] ON [Extent1].[SkillId] = [Extent2].[Id]
WHERE 5 = [Extent2].[Id]
ただし、単純な追加の where 句を追加すると、次のようになります。
from u in Users
from s in u.Skills
where s.Id == 5
&& u.Last == "test"
select new
{
u.Id,
s.Description
})
生成された SQL は、サブクエリを使用するようになりました。
[Extent1].[Id] AS [Id],
[Filter1].[Description] AS [Description]
FROM [dbo].[User] AS [Extent1]
INNER JOIN (SELECT [Extent2].[UserId] AS [UserId], [Extent3].[Description] AS [Description]
FROM [dbo].[UserSkill] AS [Extent2]
INNER JOIN [dbo].[Skill] AS [Extent3] ON [Extent3].[Id] = [Extent2].[SkillId]
WHERE 5 = [Extent3].[Id] ) AS [Filter1] ON [Extent1].[Id] = [Filter1].[UserId]
WHERE 'test' = [Extent1].[Last]
何かが足りないかもしれませんが、EF はこのクエリの User テーブルに別の結合を追加し、サブクエリを実行する代わりに User.Last で where を実行できると思います。この種の動作を強制する方法はありますか? 私は何か間違ったことをしていますか?
ありがとう。
アップデート
Cosmin さん、クエリを次のようにしてほしいと思っています。
SELECT u.Id, s.Description
FROM [User] u INNER JOIN
[UserSkill] us ON u.Id = us.UserId INNER JOIN
[Skill] s ON us.SkillId = s.Id
WHERE s.Id = 2 AND u.Last = 'test'