C# 在实体框架中添加存储过程复杂类型

C# 在实体框架中添加存储过程复杂类型,c#,stored-procedures,entity-framework-4,silverlight-4.0,C#,Stored Procedures,Entity Framework 4,Silverlight 4.0,我试图在实体框架中使用一个不返回任何内容的存储过程 我做了以下工作: 添加了一个函数(右键单击存储过程->添加->函数导入->复杂类型->获取列信息->创建新的复杂类型) 我的函数名:summarySP\u Result。构建项目后,实体类不会在generated\u code(BusinessAccount.web.g.cs)中生成 但表和视图的实体类都是为存储过程创建的,而不是为存储过程创建的 create procedure [dbo].[usp_InsertOrUpdate] /*if

我试图在实体框架中使用一个不返回任何内容的存储过程

我做了以下工作:

  • 添加了一个函数(右键单击存储过程->添加->函数导入->复杂类型->获取列信息->创建新的复杂类型)

  • 我的函数名:
    summarySP\u Result
    。构建项目后,实体类不会在
    generated\u code
    BusinessAccount.web.g.cs
    )中生成

  • 但表和视图的实体类都是为存储过程创建的,而不是为存储过程创建的

    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
    
    有人能告诉我为什么它不是在
    BusinessAccount.web.g.cs
    中生成的实体类吗

    更新:

    让我确认在您的
    XXXXXX.web.g.cs
    类中创建的
    ReturnDataFromTemTable\u结果
    实体类

    比如:

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

    好的-以下是一步一步的方法:

    (1) 将存储过程添加到EDMX文件中(当您第一次创建它时,或稍后使用
    从数据库更新模型
    并拾取该存储过程时)

    (2) 模型中有存储过程后-使用
    模型浏览器
    添加
    函数导入

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

    (4) 完成后,您现在应该可以在模型浏览器的“概念模型”部分中看到存储过程,并且新生成的复杂类型也应该显示在那里:


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


    这看起来像是Visual Studio 2012中的一个bug,我正在使用它,我还没有应用Update 1,我将尝试看看它是否可以修复。

    这是为Ross Brigoli准备的

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

    快速启动 您可以在完成导入后删除此项

    资料来源:-

    这是我的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,我会帮你的。 如果存储过程更新,则更新复杂类型

    对于我来说,将存储过程导入EF并不会(自动)生成复杂的实体返回对象,我遇到了一些问题。然而,在注释了存储过程(又名存储过程)的各个部分后,我发现当我重新导入存储过程时(即使用函数导入编辑屏幕中的“获取列信息”按钮刷新),可以生成复杂类型

    简而言之,可能有一个where子句(或者其他什么)导致EF不生成复杂类型。尝试注释存储过程的各个部分,然后将存储过程重新导入到

    更新:

    在上面的调查之后,我发现没有生成复杂实体的原因是因为我的存储过程使用的是视图(而不是典型的表)。出于好奇,我将视图更改为另一个表,只是为了看看会发生什么,然后生成了复杂的实体

    因此,简而言之,如果您有一个视图,复杂实体可能不会自动生成。为了尝试,我临时删除了视图,重新导入存储过程,生成了复杂的实体,然后将视图放回。但现在我的代码给出了例外

    稍后当我了解更多信息时将对此进行更新=)

    更新:


    修正了这个问题。真是愚蠢的错误!我使用的viewname没有拼写为right=D。我有点生气,因为我创建存储过程时Sql Server没有抛出错误。。。。。我想这就是生活:)唉,问题现在解决了

    EF不支持导入从以下位置生成结果集的存储过程:

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

    正如Sandeep所说,
    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
    
    EF不支持导入从动态查询或临时表生成结果集的存储过程

    但您不必重写整个SP

    只需编写另一个名称相同的文件,返回正确的行格式,而无需使用动态SQL或临时表。然后使用EF SP adding函数,该函数现在将自动生成复杂类型

    编辑:实际上,在SP顶部进行注释更容易,它可以立即选择所需的行,其中包含使用强制转换指定的所有数据类型。当您需要将SP导入EF时,只需取消对代码的注释

    e、 g

    创建过程myProc()
    AS
    开始
    --取消注释以下要导入的行:
    --选择CAST(0作为int)作为column1Name,选择CAST('a'作为varchar(50))作为clun2name

    --要导入SP内容时,请将其注释掉。
    <正确的SP内容>
    结束

    然后删除存储的进程并创建原始进程。

    不过,请保存您制作的临时导入SP,以防再次需要它

    要正确添加复杂类型,请转到模型浏览器,右键单击函数,然后显示编辑,单击编辑并填充对话框。函数的名称应与存储过程的名称相同。点击OK按钮。现在函数被创建。然后右c