2012-08-27 82 views
1

SQL分析器顯示EF發出相同的查詢高達8倍從以下LINQ查詢:如何避免實體框架發出重複查詢?

var query = (from wtv in _context.WorkTypeVersions 
       join rc in _context.RateCategories on wtv.WTVID equals rc.WTVID 
       join rsc in _context.RateSubCategories on rc.RCID equals rsc.RCID 
       where (wtv.Composite == (ckCompositePreambles.Checked ? "Y" : "N") 
         && rc.CatCode == catCode) 

       select new pRateSubCategory() 
       { 
        WTVID = wtv.WTVID, 
        RSCID = rsc.RSCID, 
        WTVersionName = wtv.WTVersionName, 
        SubCatCode = rsc.SubCatCode, 
        PCode = rsc.Preamble.SectionCode, 
        RateCategoryName = rc.RateCategoryName, 
        RateSubCategoryName = rsc.RateSubCategoryName, 
        FullSubCatName = rsc.FullSubCatName, 
        PMBID = rsc.PMBID, 
        Preamble = rsc.Preamble 
       }); 

    dgvRateSubCategories.AutoGenerateColumns = false; 
    lblSubSectionCount.Text = "SubSections: " + bsRateSubCategories.Count; 
    dgvRateSubCategories.DataSource = bsRateSubCategories; 

    bsRateSubCategories.DataSource = query; 

的TSQL查詢(產生高達8倍,雖然其它的散佈)是這樣的:

exec sp_executesql N'SELECT 
    [Project1].[WTVID] AS [WTVID], 
    [Project1].[RSCID] AS [RSCID], 
    [Project1].[WTVersionName] AS [WTVersionName], 
    [Project1].[SubCatCode] AS [SubCatCode], 
    [Project1].[SectionCode] AS [SectionCode], 
    [Project1].[RateCategoryName] AS [RateCategoryName], 
    [Project1].[RateSubCategoryName] AS [RateSubCategoryName], 
    [Project1].[FullSubCatName] AS [FullSubCatName], 
    [Project1].[PMBID] AS [PMBID], 
    [Project1].[PMBID1] AS [PMBID1], 
    [Project1].[PMB_Level] AS [PMB_Level], 
    [Project1].[PMB_Text] AS [PMB_Text], 
    [Project1].[Composite] AS [Composite], 
    [Project1].[PMB_XPS] AS [PMB_XPS] 
    FROM (SELECT 
     [Extent1].[WTVID] AS [WTVID], 
     [Extent1].[WTVersionName] AS [WTVersionName], 
     [Extent2].[RateCategoryName] AS [RateCategoryName], 
     [Extent3].[RSCID] AS [RSCID], 
     [Extent3].[PMBID] AS [PMBID], 
     [Extent3].[RateSubCategoryName] AS [RateSubCategoryName], 
     [Extent3].[SubCatCode] AS [SubCatCode], 
     [Extent3].[FullSubCatName] AS [FullSubCatName], 
     [Extent4].[PMBID] AS [PMBID1], 
     [Extent4].[PMB_Level] AS [PMB_Level], 
     [Extent4].[SectionCode] AS [SectionCode], 
     [Extent4].[Composite] AS [Composite], 
     [Extent4].[PMB_Text] AS [PMB_Text], 
     [Extent4].[PMB_XPS] AS [PMB_XPS] 
     FROM [dbo].[WorkTypeVersions] AS [Extent1] 
     INNER JOIN [dbo].[RateCategories] AS [Extent2] ON [Extent1].[WTVID] = [Extent2].[WTVID] 
     INNER JOIN [dbo].[RateSubCategories] AS [Extent3] ON [Extent2].[RCID] = [Extent3].[RCID] 
     LEFT OUTER JOIN [dbo].[Preambles] AS [Extent4] ON [Extent3].[PMBID] = [Extent4].[PMBID] 
     WHERE ([Extent1].[Composite] = (CASE WHEN (@p__linq__0 = 1) THEN N''Y'' ELSE N''N'' END)) AND ([Extent2].[CatCode] = @p__linq__1) 
    ) AS [Project1] 
    ORDER BY [Project1].[SubCatCode] ASC, [Project1].[WTVersionName] ASC',N'@p__linq__0 bit,@p__linq__1 varchar(8000)',@p__linq__0=0,@p__linq__1='A'  

EF的版本目前是:System.Data.Entity:4.0.0.0,EntityFramework:4.3.1

我在這裏丟失了什麼?

+1

什麼是'dgvRateSubCategories'的類型,並嘗試像'bsRateSubCategories.DataSource = query.ToList();'綁定數據源來防止網格查詢。 –

回答

3

的問題是,你要設置數據源:

bsRateSubCategories.DataSource = query; 

query變量實現擴展了IEnumerable<T> interface(其中DataSource要求)的IQueryable<T> interface。當你將它綁定到一個網格時,網格將多次枚舉結果以便呈現它自己。

但是,因爲你已經用它實現IQuerable<T>每時間查詢被列舉的數據源,提供的網格,它將對服務器執行,這可能是你看到它這樣的原因查詢多次。

爲了緩解這種情況,分配給DataSource之前,你應該兌現你的列表,或者與ToList擴展方法,像這樣(如果它是隻讀的,ToArray將被罰款,但如果你需要增加新的項目,然後使用ToList):

bsRateSubCategories.DataSource = query.ToList(); 

當然,你必須決定什麼時候適合重置DataSource像現在的數據源是完全與服務器斷開連接。

+0

非常感謝@casperOne! - 對SQL Azure有很大的影響。順便說一句,我不得不在需要添加新記錄的網格上使用ToList()而不是ToArray()。 – Mivoat

+0

@Mivoat更新了帖子以反映這一點。很高興它有幫助。 – casperOne