简体   繁体   English

LINQ-to-SQL:返回单个标量值的存储过程?

[英]LINQ-to-SQL: Stored Procedure that returns a single scalar value?

I am using LINQ-to-SQL for an application that queries a legacy database. 我正在使用LINQ-to-SQL来查询旧数据库的应用程序。 I need to call a stored procedure, that selects a single integer value. 我需要调用一个存储过程,它选择一个整数值。 Changing the stored procedure is not an option. 无法更改存储过程。

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. 我希望返回类型为int。 How do I do this using LINQ-to-SQL ? 如何使用LINQ-to-SQL执行此操作?

This would be trivial with a scalar function (UDF) rather than an SP. 对于标量函数(UDF)而不是SP,这将是微不足道的。 However, it should work easily enough - although if the SP is complex (ie FMT_ONLY can't inspect it 100%) then you might need to "help" it... 但是,它应该足够容易 - 虽然如果SP很复杂(即FMT_ONLY无法100%检查它),那么你可能需要“帮助”它......

Here's some dbml that I generated from a simplfied SP that returns an integer; 这是我从一个返回整数的simplfied SP生成的一些dbml; you can edit the dbml via "open with... xml editor): 你可以通过“open with ... xml editor”编辑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. 如果您当前的SP使用SELECT(而不是RETURN),那么DBML将需要反映这一点。 You can fix this by hiding the implementation details, and providing a public wrapper in a partial class; 您可以通过隐藏实现细节并在分部类中提供公共包装来解决此问题; for example: 例如:

<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; 以上描述了一个返回单个表的SP的SP; but I've made the SP "private" to the data-context, and the result-type "internal" to the assembly (hiding it): 但我已经使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 file I 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't edit the designer.cs file directly; 不要直接编辑designer.cs文件; your changes will be lost. 你的改变将会丢失。 Only edit either the dbml or partial classes. 仅编辑dbml或partial类。

RETURN @VALUE as the last statement of the proc. 将@VALUE作为proc的最后一个语句返回。

then it will auto detect the type int, string, bool etc and generate the wrapper method accordingly. 然后它将自动检测int,string,bool等类型,并相应地生成包装器方法。

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文件,请确保:

  1. Right click the stored procedure or function call in the Adapter. 右键单击适配器中的存储过程或函数调用。
  2. Select Properties 选择属性
  3. 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,或者它应该是什么类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM