LINQ to SQL - 无法修改存储过程的返回类型

Kyl*_*yan 20 stored-procedures asp.net-3.5 linq-to-sql

当我将特定的存储过程拖到VS 2008 dbml设计器中时,它会显示返回类型设置为"none",并且它是只读的,因此我无法更改它.设计器代码将其显示为返回int,如果我手动更改它,它将在下一个构建时撤消.

但是使用另一个(几乎相同的)存储过程,我可以很好地改变返回类型(从"自动生成类型"到我想要的.)

我在两台独立的机器上遇到了这个问题.知道发生了什么事吗?

这是有效的存储过程:

USE [studio]
GO
/****** Object:  StoredProcedure [dbo].[GetCourseAnnouncements]    Script Date: 05/29/2009 09:44:51 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER OFF
GO
CREATE PROCEDURE [dbo].[GetCourseAnnouncements]
    @course int
AS
SELECT * FROM Announcements WHERE Announcements.course = @course
RETURN
Run Code Online (Sandbox Code Playgroud)

而这个不是:

USE [studio]
GO
/****** Object:  StoredProcedure [dbo].[GetCourseAssignments]    Script Date: 05/29/2009 09:45:32 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER OFF
GO
CREATE PROCEDURE [dbo].[GetCourseAssignments]
    @course int
AS
SELECT * FROM Assignments WHERE Assignments.course = @course ORDER BY date_due ASC
RETURN
Run Code Online (Sandbox Code Playgroud)

Eri*_*ing 19

我也曾多次看到这个问题,虽然我不知道是什么原因引起的,但我遇到了一个很简单的方法.它涉及在.dbml文件中手动编辑xml,但这是一个非常简单的编辑.

右键单击.dbml解决方案资源管理器中的数据上下文文件(不是.layout文件或designer.cs文件),然后使用XML编辑器打开它.您应该找到<Function> ... </Function>块中列出的存储过程.您还应该找到要设置为<Type> ... </Type>块中列出的返回类型的自定义类.

第一步是为您的自定义类提供标识符.您可以通过添加"Id"标记来实现此目的,确保它在dbml文件中是唯一的:

<Type Name="MyCustomClass" Id="ID1">
Run Code Online (Sandbox Code Playgroud)

第二步是告诉你的函数使用新的ID类型作为返回类型.您可以通过这样做更换你的行<Function>块,看起来像

<Return Type="System.Int32" />
Run Code Online (Sandbox Code Playgroud)

<ElementType IdRef="ID1" />
Run Code Online (Sandbox Code Playgroud)

保存文件,退出并重建.完成.在设计模式下重新打开.dbml文件以验证:您的过程现在将自定义类设置为返回类型.


小智 13

我有一个类似的映射问题,但我在我的案例中找到了罪魁祸首.

如果您的过程或被调用的任何子过程都有临时对象,如

CREATE TABLE #result (
   ID INT,
   Message VARCHAR(50)
)
Run Code Online (Sandbox Code Playgroud)

那么你就麻烦了,即使你没有选择这些临时任何东西.

映射器具有这些临时对象的一般问题,因为可以在会话上下文中的过程之外更改类型.对于映射器,临时对象不是类型安全的,他拒绝使用它们.

用表变量替换它们,然后你又回来了

DECLARE @result AS TABLE (
   ID INT,
   Message VARCHAR(50)
)
Run Code Online (Sandbox Code Playgroud)


小智 9

我按照Tony提供链接获得了更好的解决方案(与Arash相同的答案)

  • 请阅读博客,尤其是最后一部分,因为在您的存储过程中添加SET FMTONLY OFF时需要考虑一下.

当你添加

 SET FMTONLY OFF
Run Code Online (Sandbox Code Playgroud)

在存储过程的开头并将其加载到DBML,
LINQ2SQL将执行实际的存储过程.

要获得正确的返回表对象类型,
所述存储过程必须在调用w/o参数时返回一些内容.
这意味着:
1.具有所有输入参数的默认值
2.确保SP至少返回一行数据 - 这是我偶然发现的地方

create table #test ( text varchar(50) );
insert into #test (text) values ('X'); -- w/o this line, return type would be Int32
select * from #test; -- SP returns something, proper object type would be generated
return;
Run Code Online (Sandbox Code Playgroud)


Kyl*_*yan 5

好的,我发现了问题......有点儿.我更改了"Assignments"表的名称并忘记更新存储的procudure,因此DBML设计者感到困惑.即使我更新了存储过程后,将其从DBML设计器中删除并读取它,它也无法正常工作!

这几乎与此处讨论的问题相同:http://forums.asp.net/t/1231821.aspx.

它只在我从数据库中删除存储过程并重新创建它,并从DBML设计器中删除它,重新编译,重新启动Visual Studio并再次添加它时才起作用.这是我第二次遇到Visual Studio DBML设计器的"刷新"问题......


小智 5

我设法找到了一种更简单的方法,当时并不明显,但写下来时听起来很直接:

  1. 从.dbml文件的设计图面中删除存储过程
  2. 单击保存所有文件
  3. 单击存储过程列表中的服务器资源管理器中的刷新
  4. 将存储过程添加(拖动)回到.dbml文件的设计图面上
  5. 单击全部保存
  6. 单击构建
  7. 检查designer.cs代码文件,您将获得新版本存储过程的更新C#代码

查看http://www.high-flying.co.uk/C-Sharp/linq-to-sql-can-t-update-dbml-file.html