[英]EF Linq query with conditional include
因此,我有以下Linq查詢:
var member = (from mem in
context.Members.Include(m =>
m.MemberProjects.Select(mp => mp.Project))
where mem.MemberId == memberId
select mem).FirstOrDefault();
這將返回一個Member實體,以及一組具有Project子項的MemberProjects。 我想將MemberProjects限制為那些Project子項具有屬性ProjectIdParent == null
。
我的一次失敗嘗試可能使意圖更清晰:
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();
當然,這會因為Where子句而抱怨包含表達式無效。
關於如何執行此操作的任何想法都很棒:)
免責聲明:我尚未對此進行測試。 這只是一個想法。 如果您讓我知道結果,我將相應地進行更新。 (跳至測試部分的更新部分)
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);
我還將使用EFProfiler之類的東西來分析查詢,以確保生成的查詢不會脫離理智的境界。
您也可以查看Jimmy Bogard的這篇關於ORM的多對多關系的文章。
更新
我使用EF 6.1.3為此提出了多個經過測試的解決方案。 我的Edmx如下所示:
設置數據如下:
我能夠在下面運行代碼以正確獲取MemberFive
var member = context.Members.FirstOrDefault
(m => m.MemberId == memberId
&& m.Projects.Any(p => p.ProjectParentId == null));
生成的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)))
如果您不喜歡所生成的查詢,則可以使用以下命令:
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();
后者始終在20毫秒以下返回,而另一方則在60毫秒左右徘徊(如果這對您很重要)。
我希望這有幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.