[英]EF Linq query with conditional include
So I have the following Linq query: 因此,我有以下Linq查询:
var member = (from mem in
context.Members.Include(m =>
m.MemberProjects.Select(mp => mp.Project))
where mem.MemberId == memberId
select mem).FirstOrDefault();
This returns a Member entity, with a set of MemberProjects that have a Project child. 这将返回一个Member实体,以及一组具有Project子项的MemberProjects。 I would like to limit the MemberProjects to only those for which the Project child has a property
ProjectIdParent == null
. 我想将MemberProjects限制为那些Project子项具有属性
ProjectIdParent == null
。
One of my failed attempts might make the intent clearer: 我的一次失败尝试可能使意图更清晰:
var member = (from mem in context.Members
.Include(m => m.MemberProjects
.Where(mp =>
mp.Project.ProjectIdParent == null)
.Select(proj => proj.Project))
where mem.MemberId == memberId
select mem).FirstOrDefault();
This of course complains of an invalid Include expression because of the Where clause. 当然,这会因为Where子句而抱怨包含表达式无效。
Any thoughts on how to do this would be great :) 关于如何执行此操作的任何想法都很棒:)
DISCLAIMER: I havent tested this. 免责声明:我尚未对此进行测试。 This is just an idea.
这只是一个想法。 If you let me know the results, I will update this accordingly.
如果您让我知道结果,我将相应地进行更新。 (Skip to the update part for the tested solutions)
(跳至测试部分的更新部分)
var member = (from mps in context.MemberProjects
.Include(m => m.Members)
.Include(m => m.Projects)
where mps.Project.ProjectIdParent == null
select mps)
.FirstOrDefault(mprojs => mprojs.Member.MemberId == memberId);
I'd also analyze the queries using something like EFProfiler to make sure the generated queries dont leave the realm of sanity. 我还将使用EFProfiler之类的东西来分析查询,以确保生成的查询不会脱离理智的境界。
You can also take a look at this post by Jimmy Bogard on Many to Many relationships with ORMs. 您也可以查看Jimmy Bogard的这篇关于ORM的多对多关系的文章。
Update 更新
I came up with multiple tested solutions for this with EF 6.1.3. 我使用EF 6.1.3为此提出了多个经过测试的解决方案。 My Edmx looked like below:
我的Edmx如下所示:
The setup data is like below: 设置数据如下:
I was able to run code below to get the MemberFive correctly 我能够在下面运行代码以正确获取MemberFive
var member = context.Members.FirstOrDefault
(m => m.MemberId == memberId
&& m.Projects.Any(p => p.ProjectParentId == null));
The generated SQL looked like this: 生成的SQL如下所示:
SELECT TOP (1) [Extent1].[MemberId] AS [MemberId],
[Extent1].[MemberName] AS [MemberName]
FROM [dbo].[Members] AS [Extent1]
WHERE ([Extent1].[MemberId] = 1)
AND (EXISTS (SELECT 1 AS [C1]
FROM (SELECT [MemberProjects].[MemberId] AS [MemberId],
[MemberProjects].[ProjectId] AS [ProjectId]
FROM [dbo].[MemberProjects] AS [MemberProjects])
AS [Extent2]
INNER JOIN [dbo].[Projects] AS [Extent3]
ON [Extent3].[ProjectId] = [Extent2].[ProjectId]
WHERE ([Extent1].[MemberId] = [Extent2].[MemberId])
AND ([Extent3].[ProjectParentId] IS NULL)))
If you dont like the generated query you can use this: 如果您不喜欢所生成的查询,则可以使用以下命令:
var memberQuery = @"Select M.* from Members M
inner join MemberProjects MP on M.MemberId = Mp.ProjectId
inner join Projects P on MP.ProjectId = P.ProjectId
where M.MemberId = @MemberId and P.ProjectParentId is NULL";
var memberParams = new[]
{
new SqlParameter("@MemberId", 1)
};
var member3 = context.Members.SqlQuery(memberQuery, memberParams)
.FirstOrDefault();
The later consistently returned under 20ms vs the other one hovered around 60ms (if that matters to you). 后者始终在20毫秒以下返回,而另一方则在60毫秒左右徘徊(如果这对您很重要)。
I hope this helps. 我希望这有帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.