EF4 - 选定的存储过程不返回任何列

cjb*_*rth 60 sql-server temp-tables entity-framework-4

我在一个存储过程中查询,该存储过程使用一些动态SQL调用某些链接服务器.我知道EF不喜欢这样,所以我特意列出了所有要返回的列.然而,它仍然不喜欢这样.我在这做错了什么?我只是希望EF能够检测从存储过程返回的列,以便我可以创建我需要的类.

请参阅以下代码,它构成了我的存储过程的最后几行:

SELECT
    #TempMain.ID,
    #TempMain.Class_Data,
    #TempMain.Web_Store_Class1,
    #TempMain.Web_Store_Class2,
    #TempMain.Web_Store_Status,
    #TempMain.Cur_1pc_Cat51_Price,
    #TempMain.Cur_1pc_Cat52_Price,
    #TempMain.Cur_1pc_Cat61_Price,
    #TempMain.Cur_1pc_Cat62_Price,
    #TempMain.Cur_1pc_Cat63_Price,
    #TempMain.Flat_Length,
    #TempMain.Flat_Width,
    #TempMain.Item_Height,
    #TempMain.Item_Weight,
    #TempMain.Um,
    #TempMain.Lead_Time_Code,
    #TempMain.Wp_Image_Nme,
    #TempMain.Wp_Mod_Dte,
    #TempMain.Catalog_Price_Chg_Dt,
    #TempMain.Description,
    #TempMain.Supersede_Ctl,
    #TempMain.Supersede_Pn,
    TempDesc.Cust_Desc,
    TempMfgr.Mfgr_Item_Nbr,
    TempMfgr.Mfgr_Name,
    TempMfgr.Vendor_ID
FROM
    #TempMain
        LEFT JOIN TempDesc ON #TempMain.ID = TempDesc.ID
        LEFT JOIN TempMfgr ON #TempMain.ID = TempMfgr.ID
Run Code Online (Sandbox Code Playgroud)

Lad*_*nka 146

EF不支持导入构建结果集的存储过程:

  • 动态查询
  • 临时表

原因是要导入程序,EF必须执行它.此类操作可能很危险,因为它可能会触发数据库中的某些更改.因为EF在执行存储过程之前使用特殊的SQL命令:

SET FMTONLY ON
Run Code Online (Sandbox Code Playgroud)

通过执行此命令,存储过程将仅返回有关其结果集中的列的"元数据",并且不会执行其逻辑.但由于逻辑没有执行,因此没有临时表(或构建动态查询),因此元数据不包含任何内容.

您有两个选择(除了需要重写存储过程以不使用这些功能的选项):

  • 手动定义返回的复杂类型(我想它应该工作)
  • 使用hack只是为了添加在其开头放置的存储过程SET FMTONLY OFF.这将允许您的SP代码的其余部分以正常方式执行.只需确保您的SP不会修改任何数据,因为这些修改将在导入期间执行!成功导入后删除该hack.

  • 这是我的一个程序,但不是另一个.我最后修改我的过程以返回具有相同数据类型的空结果集,同时我将过程添加到设计器并在成功添加过程后还原. (9认同)
  • 对我来说关键点是"EF必须执行它",我的proc在使用null参数执行时出错 (3认同)
  • 对于我的情况,它实际上是设置SET FMTONLY OFF (3认同)
  • 如果您以正确的方式创建临时表,它支持临时表:声明 @MyTemporaryTable TABLE ( (2认同)

Mau*_*lho 12

或者,您可以创建用户定义的表类型并返回该类型.

CREATE TYPE T1 AS TABLE 
( ID bigint NOT NULL
  ,Field1 varchar(max) COLLATE Latin1_General_CI_AI NOT NULL
  ,Field2 bit NOT NULL
  ,Field3 varchar(500) NOT NULL
  );
GO
Run Code Online (Sandbox Code Playgroud)

然后在程序中:

DECLARE @tempTable dbo.T1

INSERT @tempTable (ID, Field1, Field2, Field3)
SELECT .....

....

SELECT * FROM @tempTable
Run Code Online (Sandbox Code Playgroud)

现在EF应该能够识别返回的列类型.