C# LINQ-to-SQL:返回单个标量值的存储过程?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/287106/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
LINQ-to-SQL: Stored Procedure that returns a single scalar value?
提问by driis
I am using LINQ-to-SQL for an application that queries a legacy database. I need to call a stored procedure, that selects a single integer value. Changing the stored procedure is not an option.
我将 LINQ-to-SQL 用于查询旧数据库的应用程序。我需要调用一个存储过程,它选择一个整数值。更改存储过程不是一个选项。
The designer creates a method with this signature:
设计者创建了一个带有这个签名的方法:
private ISingleResult<sp_xal_seqnoResult> NextRowNumber([Parameter(DbType="Int")] System.Nullable<int> increment, [Parameter(DbType="Char(3)")] string dataset)
I would like the return type to be int. How do I do this using LINQ-to-SQL ?
我希望返回类型为 int。如何使用 LINQ-to-SQL 执行此操作?
采纳答案by Marc Gravell
This would be trivial with a scalar function (UDF) rather than an SP. However, it should work easily enough - although if the SP is complex (i.e. FMT_ONLY can't inspect it 100%) then you might need to "help" it...
对于标量函数 (UDF) 而不是 SP,这将是微不足道的。但是,它应该很容易工作-尽管如果 SP 很复杂(即 FMT_ONLY 无法 100% 检查它),那么您可能需要“帮助”它...
Here's some dbml that I generated from a simplfied SP that returns an integer; you can edit the dbml via "open with... xml editor):
这是我从返回整数的简化 SP 生成的一些 dbml;您可以通过“使用... xml 编辑器打开”来编辑 dbml:
<Function Name="dbo.foo" Method="foo">
<Parameter Name="inc" Type="System.Int32" DbType="Int" />
<Parameter Name="dataset" Type="System.String" DbType="VarChar(20)" />
<Return Type="System.Int32" />
</Function>
(note you obviously need to tweak the names and data-types).
(请注意,您显然需要调整名称和数据类型)。
And here is the generated C#:
这是生成的 C#:
[Function(Name="dbo.foo")]
public int foo([Parameter(DbType="Int")] System.Nullable<int> inc, [Parameter(DbType="VarChar(20)")] string dataset)
{
IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), inc, dataset);
return ((int)(result.ReturnValue));
}
If your current SP uses SELECT (instead of RETURN), then the DBML will need to reflect this. You can fix this by hiding the implementation details, and providing a public wrapper in a partial class; for example:
如果您当前的 SP 使用 SELECT(而不是 RETURN),那么 DBML 将需要反映这一点。您可以通过隐藏实现细节并在分部类中提供公共包装器来解决此问题;例如:
<Function Name="dbo.foo" Method="FooPrivate" AccessModifier="Private">
<Parameter Name="inc" Type="System.Int32" DbType="Int" />
<Parameter Name="dataset" Type="System.String" DbType="VarChar(20)" />
<ElementType Name="fooResult" AccessModifier="Internal">
<Column Name="value" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" />
</ElementType>
</Function>
The above describes an SP that returns a single table with a single column; but I've made the SP "private" to the data-context, and the result-type "internal" to the assembly (hiding it):
上面描述了一个返回单列单表的SP;但我已经将 SP 设置为数据上下文的“私有”,并将结果类型设置为程序集的“内部”(隐藏它):
[Function(Name="dbo.foo")]
private ISingleResult<fooResult> FooPrivate(
[Parameter(DbType="Int")] System.Nullable<int> inc,
[Parameter(DbType="VarChar(20)")] string dataset)
{
IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), inc, dataset);
return ((ISingleResult<fooResult>)(result.ReturnValue));
}
Now in my own class fileI can add a new partial class (a new .cs file) in the correct namespace, that exposes the method more conveniently:
现在在我自己的类文件中,我可以在正确的命名空间中添加一个新的部分类(一个新的 .cs 文件),这样可以更方便地公开方法:
namespace MyNamespace {
partial class MyDataContext
{
public int Foo(int? inc, string dataSet)
{
return FooPrivate(inc, dataSet).Single().value;
}
}
}
(the namespace and context names need to be the same as the actual data-context). This adds a public method that hides the grungy details from the caller.
(命名空间和上下文名称需要与实际数据上下文相同)。这添加了一个公共方法,该方法对调用者隐藏了肮脏的细节。
Don'tedit the designer.cs file directly; your changes will be lost. Only edit either the dbml or partial classes.
不要直接编辑designer.cs文件;您的更改将丢失。仅编辑 dbml 或部分类。
回答by Mark Henke
RETURN @VALUE as the last statement of the proc.
RETURN @VALUE 作为 proc 的最后一条语句。
then it will auto detect the type int, string, bool etc and generate the wrapper method accordingly.
然后它将自动检测类型 int、string、bool 等并相应地生成包装方法。
回答by ansielf
If you are using Visual Studio's .xsd file in a Linq to SQL classes project, make sure you:
如果您在 Linq to SQL 类项目中使用 Visual Studio 的 .xsd 文件,请确保:
- Right click the stored procedure or function call in the Adapter.
- Select Properties
- Change Execute Mode to Scalar
- 右键单击适配器中的存储过程或函数调用。
- 选择属性
- 将执行模式更改为标量
That will make your adapter function return type to "Object". You then need to cast it to int or string, or whatever type it should be.
这将使您的适配器函数返回类型为“对象”。然后您需要将它转换为 int 或 string,或者它应该是的任何类型。