SelectMany导致查询

时间:2017-08-31 10:35:48

标签: linq-to-entities

在我的数据库中,我有四个表相互连接:backlog - > backlogsap - > partner - > contactprofile

partnercontactprofile之间存在一对多的关系。现在,我有一个积压的ID,我希望将所有联系人资料都连接到它,以便我做以下事情:

dbContext.backlogs
    .Where(bl => bl.IdBacklog == idBacklog)
    .SelectMany(bl => bl.backlogsap.partner.contactprofiles)

(是的,在这种特殊情况下,ID是不同的,所以我可以轻松地用单个子句交换where,然后只是获取联系人配置文件,但为了理解,让我们假设在哪里子句可能会返回多行。)

这会产生如下查询:

SELECT Join1.IdContactProfile, 
       Join1.Name, 
       Join1.EmailAddress, 
       Join1.LandlinePhone, 
       Join1.MobilePhone, 
       Join1.UseMail, 
       Join1.UseMobile, 
       Join1.IDPARTNER1 AS IdPartner
FROM backlog AS Extent1
INNER JOIN (SELECT Extent2.IdBacklogSap, 
                   Extent2.IdPartner, 
                   Extent2.IsDeleted, 
                   Extent2.CustomerOrderNumber, 
                   Extent2.CustomerOrderItemPosition, 
                   Extent2.CustomerOrderDate, 
                   Extent2.DeliveryDate, 
                   Extent2.CustomerReference, 
                   Extent2.IdOrderType, 
                   Extent2.NumberOrdered, 
                   Extent2.NumberAffirmed, 
                   Extent2.IdPositionType, 
                   Extent2.VoucherAmountInCent, 
                   Extent2.VoucherNumber, 
                   Extent2.SellingOrganizationName, 
                   Extent2.PurchaseOrderNumber, 
                   Extent2.PurchaseOrderItemPosition, 
                   Extent2.PurchaseOrderDate, 
                   Extent2.IdDistributionCenter, 
                   Extent2.IdMaterial, 
                   Extent2.Priority, 
                   Extent2.CreatedAt, 
                   Extent2.UpdatedAt, 
                   Extent2.UpdateOfDeliveryDateProcessed, 
                   Extent3.IdContactProfile, 
                   Extent3.Name, 
                   Extent3.EmailAddress, 
                   Extent3.LandlinePhone, 
                   Extent3.MobilePhone, 
                   Extent3.UseMail, 
                   Extent3.UseMobile, 
                   Extent3.IdPartner AS IDPARTNER1
            FROM backlogsap AS Extent2
            INNER JOIN contactprofile AS Extent3 
                    ON Extent2.IdPartner = Extent3.IdPartner) AS Join1
        ON Extent1.IdBacklogSAP = Join1.IdBacklogSap
 WHERE Extent1.IdBacklog = @p__linq__0

问题在于内部选择对大量数据起作用,这些数据连接在一起导致如此高的计算量,以至于触发数据库超时并返回错误。只有当计算结束时才会通过where子句实际减少数据。

我对这个陈述感到有点惊讶,发现当我需要的只是这个时候很奇怪:

SELECT Extent3.IdContactProfile, 
       Extent3.Name, 
       Extent3.EmailAddress, 
       Extent3.LandlinePhone, 
       Extent3.MobilePhone, 
       Extent3.UseMail, 
       Extent3.UseMobile, 
       Extent3.IdPartner
FROM backlog                                                AS Extent1
INNER JOIN backlogsap                                       AS Extent2
        ON Extent1.IdBacklogSAP = Extent2.IdBacklogSap
INNER JOIN contactprofile                                   AS Extent3
        ON Extent2.IdPartner = Extent3.IdPartner
WHERE Extent1.IdBacklog = @p__linq__0

计算和获取数据只需0.016秒。当然,持续时间可能会改变,因为其中的积压条目不止一个,但与其他查询相比,它可以忽略不计。

我目前使用以下内容绕过该查询:

dbContext.backlogs
    .Where(bl => bl.IdBacklog == idBacklog)
    .Join(this.DbContext.backlogsaps,
        bl => bl.IdBacklogSAP,
        blsap => blsap.IdBacklogSap,
        (bl, blsap) => new { Backlog = bl, BacklogSap = blsap })
    .Join(this.DbContext.contactprofiles,
        join => join.BacklogSap.IdPartner,
        cp => cp.IdPartner,
        (join, cp) => cp)

这会产生所需的查询并快速完成。但是,我发现连接方法很有吸引力,并且更喜欢像最初预期的那样的语句。另外,我想知道为什么SelectMany语句会导致查询中的嵌套选择以及如何能够避免它并实际获得简短查询。

0 个答案:

没有答案