2017-05-08 32 views
0

:這是建立在[的MySQL]EF6生成的查詢垃圾:消除多餘null檢查

說我有一個主=>詳細結構,具有以下的LINQ查詢所表示的:

IQueryable query = from master in myschema_master 
        join detail in myschema_detail 
        on detail.correlator equals request.id 
        select new 
        { 
         Id = master.id, 
         Attribute = detail.interestingcolumn 
        } 

說,如果我直接對數據庫執行以下查詢,我的〜2M的記錄集開始在約2秒

返回

注意:這不就是EF提供程序發送到數據庫上面的語句查詢)

select * 
from myschema_master 
inner join myschema_detail 
    on myschema_master.id = myschema_detail.correlator 

說我想實體框架^發送到數據庫。 如何防止它發送這種垃圾上漲了自己內心的末尾加入:

OR ((`Extent1`.`correlator` IS NULL) AND (`Extent2`.`id` IS NULL)) 

爲背景,正在由提供者發送給數據庫的完整的查詢是:

SELECT 
     1 AS `C1`, 
     `Extent1`.`id`, 
     `Extent2`.`interestingattribute` 
FROM `myschema_master` AS `Extent1` 
INNER JOIN `myschema_detail` AS `Extent2` 
    ON ((`Extent1`.`id`) = `Extent2`.`correlator`) 
    OR (
      (`Extent1`.`id` IS NULL) 
     AND (`Extent2`.`correlator` IS NULL) 
     ) 

也WIK:id和相關字段是空Int64和當前不能被修改,但我想完全消除空ç哎呀,EF和底層提供者正在發送到數據庫。 (master.id爲null並且detail.correlator爲null)創建了一個毫無價值的笛卡爾乘積,只是浪費處理時間

 

也還WIK ...我試圖與配置執行。 UseDatabaseNullSemantics設置爲true和false(...在單獨的往返行程中,明智的人),並且不刪除IS NULL等同性檢查。這是一個長鏡頭,但我從不需要明確設置屬性,所以不確定它會做什麼。

+0

這在技術上是一個重複[實體框架LINQ到實體加入查詢超時(http://stackoverflow.com/questions/42973300/entity-framework- linq-to-entities-join-query-timeout),儘管從其他帖子標題中不太清楚。 –

+0

我看到了鏈接的帖子,但解決方案不足。由此產生的輸出是一個基於equi-join的地方,而不是正確的查詢。這不是重複的 –

+0

你認爲'1 = 1'上的'JOIN'是一個「正確的」?而且真的是一個「加入」?來吧:)'UseDatabaseNullSemantics = true'和'where'基於連接是適當的解決方案。無論如何,正如您從我的第一條評論中可以看到的那樣,我不打算將其作爲重複關閉,因此不用擔心 - 評論僅針對潛在的未來讀者。 –

回答

0

解決方案與改變的功能,

第一個可行的解決方案,我可以想出這是消除在查詢中加入條件,推動過濾到哪裏。這會導致以下Linq查詢。

IQueryable query = from master in myschema_master 
        join detail in myschema_detail 
        on 1 equals 1 
        where detail.correlator == (Int64?)master.id 
        select new 
        { 
         Id = master.id, 
         Attribute = detail.interestingcolumn 
        }; 
//In LinqPad 
(this as IObjectContextAdapter).ObjectContext.CommandTimeout = 120; 
this.Configuration.UseDatabaseNullSemantics = true; 
var set = query.Dump(); 

//Outside of LinqPad, just set^on Context and materialize the 
//IEnumerable as you normally would 

得到的SQL爲

SELECT 
1 AS `C1`, 
`Extent1`.`id`, 
`Extent2`.`interestingcolumn`  
FROM `my_schema_master` AS `Extent1` 
    INNER JOIN `myschema_detail` AS `Extent2` ON 1 = 1 
WHERE `Extent2`.`correlator` = (`Extent1`.`id`)