实体框架在不同的工作站上生成不同的查询

时间:2013-05-20 13:46:14

标签: c# linq entity-framework firebird

我们在单个开发者机器和一些客户端上遇到问题。 单Linq查询生成两个不同的SQL查询。问题实际上是第二个查询具有firebird不支持的“OUTER APPLY”语句。 我们认为这不是Code问题,而是环境问题,但我会粘贴代码。

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();

使用OUTER APPLY的SQL

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 Engine生成的查询(我们在APP中支持两个数据库引擎)

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)    

2 个答案:

答案 0 :(得分:1)

您是在针对SQL Server开发吗?

如果您使用的是.edmx,则ProviderManifestToken属性(通常位于XML的前10行)将指示支持的SQL功能集。这是从您从数据库创建或更新模型时使用的数据库中确定的。例如。一个常见的问题是针对SQL 2008本地数据库,然后推送到2005数据库并发现应用程序崩溃,因为它不支持SQL 2005中的datetime2。此实例中的修复是更改自动创建的值{ {1}}至2008

我不熟悉与火鸟对抗,但建议在这方面寻找。

答案 1 :(得分:1)

问题出在Net Framework 4.5和firebirdsql.data.firebirdclient.dll之间 - 当sb安装了这个版本的框架时--EntityFramework为firebird生成外部应用语句。

可能Jiri Cincura(cincura.net)应该调查它:)

问题通过将.net框架降级到4.0完整

来解决