簡體   English   中英

帶條件包含的EF Linq查詢

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM