在Entity Framework中添加存储过程复杂类型

时间:2012-10-11 06:32:38

标签: c# stored-procedures entity-framework-4 silverlight-4.0

我正在尝试在Entity Framework中使用一个不返回任何内容的存储过程。

我做了以下事情:

  1. 添加了一项功能(右键点击存储过程 - >添加 - >功能导入 - >复杂类型 - >获取列信息 - >创建新的复杂类型)

  2. 我的函数名称:summarySP_Result。构建项目后,实体类不会在Generated_codeBusinessAccount.web.g.cs)生成

  3. 但是表和视图的实体类都是创建的,但也不是存储过程。

    有人能说出为什么它不是BusinessAccount.web.g.cs生成的实体类吗?

    更新:

    让我确认ReturnDataFromTemTable_result类中创建的XXXXXX.web.g.cs实体类。

    喜欢:

    [DataContract(Namespace="http://schemas.datacontract.org/2004/07/BizFramework.Web.Model")]
    public sealed partial class ReturnDataFromTemTable_Result : Entity
    {
       -------------------
     }
    

11 个答案:

答案 0 :(得分:64)

好的 - 这是逐步实现此目的的方法:

(1)将您的存储过程添加到EDMX文件中(首次创建时,或稍后使用Update model from database并选择该存储过程)

(2)在模型中有存储过程后 - 使用Model Browser添加Function Import

enter image description here

(3)弹出的下一个对话框非常重要 - 您需要(1)定义存储过程返回复杂类型的集合,然后您需要(2)从该存储过程获取列信息知道它将返回哪些列,然后(3)告诉Visual Studio根据该列信息生成新的复杂类型:

enter image description here

(4)一旦你完成了 - 你现在应该在模型浏览器的概念模型部分看到存储过程,新生成的复杂类型也应该出现在那里:

enter image description here

答案 1 :(得分:13)

如果仍未解决此问题,请在添加功能导入后转到解决方案资源管理器,右键单击您的{name} .Context.tt文件并执行“运行自定义工具”。该方法现在将显示在派生的Context类中。

enter image description here

这似乎是Visual Studio 2012中的一个错误,我正在使用它,我没有应用Update 1,我会尝试查看是否可以修复它。

答案 2 :(得分:11)

这是Ross Brigoli

尝试将此行添加到存储过程的开头:

设置FMTONLY OFF 完成导入后,您可以将其删除。

来源: - Why can't Entity Framework see my Stored Procedure's column information?

答案 3 :(得分:3)

正如桑迪普所说, EF不支持导入从动态查询或临时表构建结果集的存储过程。

但是你不必重写整个SP。

只需编写另一个具有相同名称的,即可返回正确的行格式,而无需使用动态SQL或临时表。然后使用EF SP添加功能,该功能现在将自动生成复杂类型。

编辑:它实际上更容易在SP的顶部发表评论,立即选择所有具有CASTS指定的数据类型的行。当您需要将SP导入EF时,只需取消注释代码即可。

e.g。

创建程序myProc()
AS
BEGIN
   - 取消注释要导入的以下行:
   - SELECT CAST(0 AS int)AS column1Name,CAST(' a' AS varchar(50))AS clumn2name

- 如果要导入SP,请注释掉SP内容   <适当的SP内容>
END

然后删除存储过程并创建原始文件 保存此临时导入SP,以防万一您再次需要它。

答案 4 :(得分:2)

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

  • 动态查询
  • 临时表

重新编写存储过程以使用表变量。 记得在更新之前从模型中删除存储的procudure和函数import,因为它不会生成复杂类型,除非它还添加了存储过程。或者转到函数导入属性,并在更新存储过程后使用获取列信息功能。

答案 5 :(得分:2)

create procedure [dbo].[usp_InsertOrUpdate]
/*if your table(tbl_InsertOrUpdate) as 3 columns like uniqueid,col1,col2*/
@uniqueId bigint NULL,/*if insert send value as null or 0*/
@col1 bigint null,
@col2 [varchar](500) NULL
as
begin
set nocount ON
SET FMTONLY OFF
/* for giving result which column updated(uniqueId) and is it insert or update(IsInsert)*/
declare @varResult table (uniqueId bigint ,IsInsert bit )
/*create a var table before inserting original table*/

declare @varInsertOrUpdate table (
uniqueId bigint ,
col1 [bigint] ,
col2 [varchar]
)
/*default we are feel as update only*/
insert into @varResult (uniqueId,IsInsert) values (@uniqueId,0)
/*insert into var table*/
INSERT INTO @varInsertOrUpdate (uniqueId,col1,col2)
VALUES
(@uniqueId,@col1,@col2)
/*Insert into original table with where condition without if else*/
 INSERT INTO tbl_InsertOrUpdate (col1,col2)
 select col1,col2 from @varInsertOrUpdate
 where uniqueId!=0;
/*if its insert updating result returning table*/
 update @varResult set 
 uniqueId=IDENT_CURRENT('tbl_InsertOrUpdate'),
IsInsert=1 where @uniqueId=0;
/*updating table where @uniqueid is  null or empty*/
UPDATE tbl_InsertOrUpdate
SET col1=@col1, 
col2=@col2,
WHERE uniqueId=@uniqueId and @uniqueId!=0

select *  from @varResult

end

答案 6 :(得分:1)

这是我实施多重搜索的SP

***************************************************

    CREATE PROCEDURE [dbo].[uspSEARCH_POSITIONS]
        @OBJ_TYPE_REQUEST varchar(2000),--'FIRST_NAME;SEARCHVALUE|LAST_NAME;SEARCHVALUE|JOB_DESCRIPTION;SEARCHVALUE'
        @DELIMITER varchar(10) --'| Which seperates the col;searchvalue|col;searchvalue
    AS
    BEGIN
    SET FMTONLY OFF
        DECLARE
            @lLastName varchar(100),
            @lFirstName varchar(100),
            @lPositionNumber varchar(20),
            @lJobDescription varchar(50),
            @lJobCode varchar(20),
            @lOccupancyIndicator varchar(50),
            @ldeleimitercolsearchval varchar(10)

    SET @ldeleimitercolsearchval =';'

    CREATE TABLE #TempTable (ColSearchValues VARCHAR(2000))

    INSERT INTO #TempTable 
    SELECT * FROM [dbo].[fnSplit](@OBJ_TYPE_REQUEST,@DELIMITER)--'fname;searchvalfname|lname;searchvallname|jobcode;searchvaljobcode','|')

    SELECT @lLastName=SUBSTRING(ColSearchValues,CHARINDEX(@ldeleimitercolsearchval ,ColSearchValues)+1,LEN(ColSearchValues)) from #TempTable where lower(ColSearchValues) like '%last%'
    SELECT @lFirstName =SUBSTRING(ColSearchValues,CHARINDEX(@ldeleimitercolsearchval ,ColSearchValues)+1,LEN(ColSearchValues)) from #TempTable where lower(ColSearchValues) like '%first%'
    SELECT @lPositionNumber =SUBSTRING(ColSearchValues,CHARINDEX(@ldeleimitercolsearchval ,ColSearchValues)+1,LEN(ColSearchValues)) from #TempTable where lower(ColSearchValues) like '%position%'
    SELECT @lJobDescription=SUBSTRING(ColSearchValues,CHARINDEX(@ldeleimitercolsearchval ,ColSearchValues)+1,LEN(ColSearchValues)) from #TempTable where lower(ColSearchValues) like '%jobd%'
    SELECT @lJobCode=SUBSTRING(ColSearchValues,CHARINDEX(@ldeleimitercolsearchval ,ColSearchValues)+1,LEN(ColSearchValues)) from #TempTable where lower(ColSearchValues) like '%jobc%'
    SELECT @lOccupancyIndicator=SUBSTRING(ColSearchValues,CHARINDEX(@ldeleimitercolsearchval ,ColSearchValues)+1,LEN(ColSearchValues)) from #TempTable where lower(ColSearchValues) like '%ccupancy%'

           SELECT  [PS].[POSITION_NUMBER]
          ,[PS].[COST_CENTER]
          ,[PS].[JOB_CODE]
          ,[PS].[JOB_CODE_DESCRIPTION]
          ,[PS].[SITE_CODE]
          ,[EMP].[EMPLOYEE_ID]
          ,[EMP].[EIN]
          ,[EMP].[GRADE]
          ,[EMP].[LOGIN_ID]
          ,[EMP].[FIRST_NAME]
          ,[EMP].[LAST_NAME]
          ,LTRIM(RTRIM(ISNULL([EMP].[LAST_NAME],''))) + ',' +LTRIM(RTRIM(ISNULL([EMP].[FIRST_NAME],''))) AS [FULL_NAME]      
          ,[EMP].[DISTRICT]
          ,[EMP].[SUPERVISOR_EIN]
          ,COUNT(*) OVER() AS TOTAL_RECORD_COUNT
      FROM [DBSERVER].[dbo].[uvwPOSITION_SEARCH] PS
      LEFT JOIN [DBSERVER].[dbo].[uvwEMPLOYEES] EMP
      ON PS.POSITION_NUMBER=EMP.POSITION_NUMBER
      WHERE
            (@lLastName  IS NULL OR [LAST_NAME] LIKE '%' + @lLastName + '%')
        AND (@lFirstName IS NULL OR [FIRST_NAME] LIKE '%' + @lFirstName + '%')
        AND (@lPositionNumber IS NULL OR [PS].[POSITION_NUMBER] LIKE '%' + @lPositionNumber + '%')
        AND (@lJobDescription IS NULL OR [PS].[JOB_CODE_DESCRIPTION] LIKE '%' + @lJobDescription + '%')
        AND (@lJobCode IS NULL OR [PS].[JOB_CODE] LIKE '%' + @lJobCode + '%')
        AND (@lOccupancyIndicator IS NULL OR [EMP].[FILLED_VACANT] LIKE '%' + @lOccupancyIndicator + '%')

    END

现在,您可以使用以下

在edmx中使用高于SP的SP

Adding stored procedures complex types in Entity Framework

Why can't Entity Framework see my Stored Procedure's column information?

如果您需要更新以下SP,请为我工作。 如果存储过程更新,则更新复杂类型 How Do I Get Entity Framework To Update Complex Types?

答案 7 :(得分:1)

对我来说,我遇到的问题是将我的存储过程导入EF不会生成复杂实体返回对象(自动)。然而,我发现,在我的sproc(aka存储过程)的部分被注释之后,当我重新导入存储过程时(即使用Function Import Edit屏幕中的Get Column Information按钮刷新),复杂类型然后可以生成!

简而言之,可能有一个where子句(或者其他东西)导致EF不生成复杂类型。尝试注释掉你的sproc部分并重新导入sproc到

更新:

继上面的调查之后,我发现复杂实体未生成的原因是因为我的sproc正在使用视图(而不是典型的表)。出于好奇的缘故,我将视图更改为另一个表,只是为了看看会发生什么,以及生成的复杂实体。

因此,简而言之,如果您有视图,看起来可能不会自动生成复杂实体。为了尝试,我暂时删除了视图,重新导入了sproc,生成了Complex Entity,然后将视图重新放入。但是现在我的代码提供了例外。

稍后当我了解更多内容时会更新此内容=)

更新:

修正了问题。真傻的错!我正在使用的视图名称拼写不正确= D.我有点生气,当我创建sproc时,Sql Server没有抛出错误.....我想这就是生活:)唉,问题现在已经解决了!

答案 8 :(得分:0)

要正确添加复杂类型,请转到模型浏览器,右键单击功能,然后显示编辑,单击编辑填充对话框。函数的名称应与存储过程的名称相同。单击确定按钮。现在创建了功能。然后右键单击创建的函数并再次编辑。除复杂类型按钮外,还有一个更新按钮。使用该更新按钮更新它。现在完全创建复杂类型。

答案 9 :(得分:0)

由于不同的原因,也可能发生复杂类型的问题,而这正是我在本案中所面临的。问题是由于SPROC中的语法错误,其中临时表的定义如下- 创建表#temp(     col1 int,     col2 nvarchar(100),     col3 nvarchar(100),-注意最后的逗号     ); 令人惊讶的是,当您编译存储过程时,SQL Server不会引发任何错误。删除逗号为我们解决了这个问题。

简而言之,尽管上述某些解决方案可能会因特定问题而起作用,但我的建议是检查您的sproc中是否存在SQL可能忽略但可能是此问题的根本原因的语法错误。谢谢。

答案 10 :(得分:0)

转到模型浏览器

如果需要修改现有功能

在函数导入下>>选择要修改的函数>>单击编辑

您将需要更新功能以刷新,并且可以看到需要添加的列