【问题标题】:LINQ to SQL -- Can't modify return type of stored procedureLINQ to SQL - 无法修改存储过程的返回类型
【发布时间】:2009-05-29 16:48:39
【问题描述】:

当我将一个特定的存储过程拖到 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

【问题讨论】:

  • 我在尝试添加查询该数据库中不存在的表的 SP 时遇到了问题。

标签: linq-to-sql stored-procedures asp.net-3.5


【解决方案1】:

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

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

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

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

第二步是告诉你的函数使用新的 ID 类型作为返回类型。您可以通过 替换 &lt;Function&gt; 块中看起来像

的行来做到这一点
<Return Type="System.Int32" />

<ElementType IdRef="ID1" />

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

【讨论】:

  • 我发现我还需要编辑 .designer.cs 文件以更新存储过程方法的返回类型。否则,存储过程方法在代码中使用时仍会返回一个 int。
【解决方案2】:

我遇到了类似的映射问题,但我发现了我的问题。

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

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

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

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

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

DECLARE @result AS TABLE (
   ID INT,
   Message VARCHAR(50)
)

【讨论】:

  • 想知道这是否记录在任何地方,我一直在寻找一整天才找到这个
  • 我以这种方式重写了我的存储过程,但没有帮助。不知道为什么..
【解决方案3】:

我关注link provided by Tony 以获得更好的解决方案(与 Arash 的答案相同)

  • 请阅读该博客,尤其是最后一部分,因为在存储过程中添加 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;

【讨论】:

  • 工作正常。谢谢:)
【解决方案4】:

好的,我发现了问题……有点。我更改了“Assignments”表的名称,忘记更新存储过程,所以 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

    【讨论】:

      【解决方案6】:

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

      【讨论】:

        【解决方案7】:

        解决这个问题的方法是:

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

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

        【讨论】:

          【解决方案8】:

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

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

          【讨论】:

            【解决方案9】:

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

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

            【讨论】:

              【解决方案10】:
              【解决方案11】:

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

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

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

              我做了什么,我删除了 Function Imports 中的重复对象并更新了模型。成功了!

              问候, 克里斯

              【讨论】:

                【解决方案12】:

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

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

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

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多