21

当我将一个特定的存储过程拖到 VS 2008 dbml 设计器中时,它会显示返回类型设置为“无”,并且它是只读的,所以我无法更改它。设计器代码将其显示为返回一个 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

而这个没有:

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
4

12 回答 12

19

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

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

第一步是给你的自定义类一个标识符。您可以像这样添加一个“Id”标签,确保它在 dbml 文件中是唯一的:

<Type Name="MyCustomClass" Id="ID1">

第二步是告诉你的函数使用新的 ID 类型作为返回类型。您可以通过替换<Function>块中看起来像的行来做到这一点

<Return Type="System.Int32" />

<ElementType IdRef="ID1" />

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

于 2009-08-28T05:44:13.743 回答
15

我有一个类似的映射问题,但我发现了我的罪魁祸首。

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

CREATE TABLE #result (
   ID INT,
   Message VARCHAR(50)
)

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

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

用表变量替换它们,您就可以重新开始工作了

DECLARE @result AS TABLE (
   ID INT,
   Message VARCHAR(50)
)
于 2010-11-25T16:19:15.373 回答
12

我按照托尼提供的链接寻求更好的解决方案(与阿拉什的答案相同)

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

当你添加

 SET FMTONLY OFF

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

为了获得正确的返回表对象类型,
所述存储过程在调用无参数时必须返回一些内容。
这意味着:
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;
于 2011-03-30T08:46:16.040 回答
5

好吧,我发现了问题……有点。我更改了“Assignments”表的名称,忘记更新存储过程,所以 DBML 设计者很困惑。但是即使在我更新了存储过程,从 DBML 设计器中删除它并读取它之后,它仍然无法正常工作!

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

只有当我从数据库中删除存储过程并重新创建它,然后从 DBML 设计器中删除它,重新编译,重新启动 Visual Studio 并再次添加它时,它才有效。这是我第二次遇到 Visual Studio DBML 设计器的“刷新”问题......

于 2009-05-29T21:50:50.313 回答
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

于 2011-11-21T20:32:24.830 回答
1

我有同样的问题,但只有当我的 sp 使用 FTS 时才会发生,我所做的是“欺骗”dbml 设计器,我删除了 fts 语言的东西并且工作得很好,现在我可以更改返回类型。后来我去 sp 并再次添加 fts 并完美地工作!希望这有帮助。

于 2009-12-29T16:20:44.033 回答
1

解决这个问题的方法是:

  1. 添加“设置 fmtonly 关闭;” 到存储过程的开头。
  2. 添加该语句后,获取 DBML 为您的存储过程生成代码。

如果您的存储过程的返回类型在您的 DBML 代码中仍然是“int”,请注释整个存储过程代码,创建一个新的 SELECT 语句,其返回字段类型和名称与原始的 SELECT 语句匹配,并让 DBML 重新生成代码。它必须工作!

于 2011-02-16T03:56:40.330 回答
1

感谢@Rubenz,我还在存储过程中使用了 FTS(全文搜索)并且您的步骤有效。

我从存储过程中注释了 FTS 部分,将存储过程添加到 .dbml,然后将 FTS 部分取消注释为原始部分。

于 2012-11-02T09:16:14.700 回答
0

在存储过程中使用 sql 用户定义类型作为参数时也会发生这种情况

http://alejandrobog.wordpress.com/2009/09/23/linq-to-sql-%e2%80%94-can%e2%80%99t-modify-return-type-of-stored-procedure/

于 2009-09-23T05:25:51.267 回答
0

在这里找到更好的解决方案:http: //tonesdotnetblog.wordpress.com/2010/06/02/solution-my-generated-linq-to-sql-stored-procedure-returns-an-int-when-it-should-return -一张桌子/

于 2010-06-07T03:13:32.517 回答
0

好的,我不想更改我的 Designer.cs 代码中的任何内容,我知道有一个不同的问题,它与我的存储过程无关(无论如何我没有使用临时表)。

简单地从数据库中删除 sp 并更新模型根本没有帮助。创建的新模型仍然存在相同的问题...

我发现由于某种原因,我的 sp 副本是在 DatabaseModel -> Function Imports 中创建的。

我所做的是,我删除了 Function Imports 中的重复对象并更新了模型。有效!

问候,克里斯

于 2014-10-13T08:52:52.177 回答
0

我意识到这是一个老问题,但上述建议为我指明了正确的方向,但在我的情况下不起作用。如上所述,我最终在 Visual Studio 中使用 XML 编辑器编辑了 dbml 文件。

进入文件后,查找存储过程的 Function 部分。您很可能看不到定义返回类型的元素类型部分。我开始从另一个Function(存储过程)编辑字段,发现这太繁琐了,可能会引入问题。

我决定从 ElementType 中删除所有 Column 定义 - 但保留 ElementType 部分并保存文件。然后我从设计器中删除了存储过程并重新添加了它。然后它在 ElementType 中填写正确的列。工作得很漂亮。

于 2019-01-31T14:26:51.050 回答