2013-05-20 35 views
6

我們在單個Developer Machine和一些客戶端上遇到問題。 單個Linq查詢生成兩個不同的SQL查詢。問題實際上是第二個查詢具有firebird不支持的「OUTER APPLY」語句。 我們認爲這不是代碼問題,而是環境問題,但我會粘貼代碼。實體框架在不同的工作站上生成不同的查詢

LINQ:

AIds = (from x in context.RISK_T_ASSESS_HIST 
    where (x.ID_RISKOBJECT.HasValue && x.F_CREATEDON >= Freq.StartDate && x.F_CREATEDON <= Freq.EndDate) 
    group x by x.ID_RISKOBJECT into gr 
    let lastCreated = gr.Max(p => p.F_CREATEDON) 
    select new 
    { 
     ObjId = gr.Key 
     , 
     LastStatus = gr.Where(p => p.F_CREATEDON == lastCreated && p.ID_RISKOBJECT == gr.Key).Select(p => p.F_STATUS).FirstOrDefault() 
    }).Where(x => x.LastStatus == 0 || x.LastStatus == 1).Select(x => x.ObjId.Value).ToArray(); 

SQL與OUTER APPLY

SELECT 
"G"."ID_RISKOBJECT" AS "ID_RISKOBJECT" 
FROM (SELECT 
    "C"."A1" AS "C1", 
    "C"."K1" AS "ID_RISKOBJECT" 
    FROM (SELECT 
     "E"."ID_RISKOBJECT" AS "K1", 
     MAX("E"."F_CREATEDON") AS "A1" 
     FROM "RISK_T_ASSESS_HIST" AS "E" 
     WHERE (("E"."ID_RISKOBJECT" IS NOT NULL) AND ("E"."F_CREATEDON" >=  @p__linq__0)) AND ("E"."F_CREATEDON" <= @p__linq__1)  
     GROUP BY "E"."ID_RISKOBJECT" 
    ) AS "C") AS "G" 
OUTER APPLY (SELECT FIRST (1) 
    "I"."F_STATUS" AS "F_STATUS" 
    FROM "RISK_T_ASSESS_HIST" AS "I" 
    WHERE (((("I"."ID_RISKOBJECT" IS NOT NULL) AND ("I"."F_CREATEDON" >=  @p__linq__0)) AND ("I"."F_CREATEDON" <= @p__linq__1)) AND (("G"."ID_RISKOBJECT" =   "I"."ID_RISKOBJECT") OR (("G"."ID_RISKOBJECT" IS NULL) AND ("I"."ID_RISKOBJECT" IS  NULL)))) AND (("I"."F_CREATEDON" = "G"."C1") AND ("I"."ID_RISKOBJECT" =  "G"."ID_RISKOBJECT"))) AS "J"  
WHERE (0 = "J"."F_STATUS") OR (1 = "J"."F_STATUS") 

工作SQL

SELECT 
"B"."ID_RISKOBJECT" AS "ID_RISKOBJECT" 
FROM (SELECT 
     "C"."ID_RISKOBJECT" AS "ID_RISKOBJECT", 
     (SELECT FIRST (1) 
      "I"."F_STATUS" AS "F_STATUS" 
       FROM "RISK_T_ASSESS_HIST" AS "I" 
     WHERE (((("I"."ID_RISKOBJECT" IS NOT NULL) AND ("I"."F_CREATEDON" >= @p__linq__0)) AND ("I"."F_CREATEDON" <= @p__linq__1)) AND (("C"."ID_RISKOBJECT" = "I"."ID_RISKOBJECT") OR (("C"."ID_RISKOBJECT" IS NULL) AND ("I"."ID_RISKOBJECT" IS NULL)))) AND (("I"."F_CREATEDON" = "C"."C1") AND ("I"."ID_RISKOBJECT" = "C"."ID_RISKOBJECT"))) AS "C1" 
    FROM (SELECT 
     "D"."A1" AS "C1", 
     "D"."K1" AS "ID_RISKOBJECT" 
     FROM (SELECT 
       "F"."ID_RISKOBJECT" AS "K1", 
       MAX("F"."F_CREATEDON") AS "A1" 
       FROM "RISK_T_ASSESS_HIST" AS "F" 
       WHERE (("F"."ID_RISKOBJECT" IS NOT NULL) AND ("F"."F_CREATEDON" >= @p__linq__0)) AND ("F"."F_CREATEDON" <= @p__linq__1) 
       GROUP BY "F"."ID_RISKOBJECT" 
     ) AS "D" 
    ) AS "C"  
) AS "B" 
     WHERE (0 = "B"."C1") OR (1 = "B"."C1") 

查詢爲MSSQL引擎產生的(我們支持我們的應用程序2分貝引擎)

SELECT 
[Project1].[ID_RISKOBJECT] AS [ID_RISKOBJECT] 
FROM (SELECT 
    [GroupBy1].[A1] AS [C1], 
    [GroupBy1].[K1] AS [ID_RISKOBJECT] 
    FROM (SELECT 
     [Extent1].[ID_RISKOBJECT] AS [K1], 
     MAX([Extent1].[F_CREATEDON]) AS [A1] 
     FROM [dbo].[RISK_T_ASSESS_HIST] AS [Extent1] 
     WHERE ([Extent1].[ID_RISKOBJECT] IS NOT NULL) AND ([Extent1].[F_CREATEDON] >= @p__linq__0) AND ([Extent1].[F_CREATEDON] <= @p__linq__1) 
     GROUP BY [Extent1].[ID_RISKOBJECT] 
    ) AS [GroupBy1]) AS [Project1] 
OUTER APPLY (SELECT TOP (1) 
    [Extent2].[F_STATUS] AS [F_STATUS] 
    FROM [dbo].[RISK_T_ASSESS_HIST] AS [Extent2] 
    WHERE ([Extent2].[ID_RISKOBJECT] IS NOT NULL) AND ([Extent2].[F_CREATEDON] >=  @p__linq__0) AND ([Extent2].[F_CREATEDON] <= @p__linq__1) AND (([Project1].[ID_RISKOBJECT] = [Extent2].[ID_RISKOBJECT]) OR (([Project1].[ID_RISKOBJECT] IS NULL) AND ([Extent2]. [ID_RISKOBJECT] IS NULL))) AND ([Extent2].[F_CREATEDON] = [Project1].[C1]) AND ([Extent2].[ID_RISKOBJECT] = [Project1].[ID_RISKOBJECT])) AS [Limit1]  
WHERE [Limit1].[F_STATUS] IN (0,1)  
+0

你在使用EF的方法呢?先寫代碼或數據庫?即你是從DbContext和DbSet繼承還是你有.edmx的xml文件? –

+0

數據庫首先,由於遺留問題,我們有edmx。如果需要的話,我可以提供。 – Lightning3

+0

我們也支持mssql,我會做一些測試,並且我會報告 – Lightning3

回答

1

您正在開發針對SQL Server嗎?

如果您使用的是.edmx,那麼ProviderManifestToken屬性(通常位於XML的前10行)將指示支持的一組SQL特徵。這是從您從數據庫創建或更新模型時使用的數據庫確定的。例如。一個常見問題是針對SQL 2008本地數據庫,然後推送到2005數據庫,並發現該應用程序崩潰,因爲它不支持SQL 2005中的datetime2。此實例中的修復程序是將自動創建的值從20082005

我不熟悉與火鳥工作,但建議在這方面看。

+0

我們有這個問題:)像你說的,在mssql我們修復它,目前:ProviderManifestToken =「2008」正常。 – Lightning3

+0

我將從firebird粘貼整行: Lightning3

+0

在MSSQL上一切正常,問題是特定於火鳥:( – Lightning3

1

問題出在Net Framework 4.5和firebirdsql.data.firebirdclient.dll之間 - 當sb安裝了這個版本的框架時 - EntityFramework爲firebird生成外部應用語句。

大概吉日Cincura(cincura.net)應調查吧:)

問題被降級的.NET Framework解決了4.0全