LINQ-to-SQL: хранимая процедура, которая возвращает одно скалярное значение? - PullRequest
12 голосов
/ 13 ноября 2008

Я использую LINQ-to-SQL для приложения, которое запрашивает устаревшую базу данных. Мне нужно вызвать хранимую процедуру, которая выбирает одно целое значение. Изменение хранимой процедуры не вариант.

Дизайнер создает метод с такой подписью:

private ISingleResult<sp_xal_seqnoResult> NextRowNumber([Parameter(DbType="Int")] System.Nullable<int> increment, [Parameter(DbType="Char(3)")] string dataset)

Я бы хотел, чтобы тип возвращаемого значения был int. Как мне сделать это с помощью LINQ-to-SQL?

Ответы [ 3 ]

13 голосов
/ 13 ноября 2008

Это было бы тривиально с скалярной функцией (UDF), а не с SP. Тем не менее, он должен работать достаточно легко - хотя если SP сложный (то есть FMT_ONLY не может проверить его на 100%), то вам, возможно, придется «помочь» ему ...

Вот некоторый dbml, который я сгенерировал из упрощенного SP, который возвращает целое число; Вы можете редактировать dbml через "Открыть с помощью ... XML-редактор":

<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>

(обратите внимание, что вам, очевидно, нужно настроить имена и типы данных).

А вот сгенерированный 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));
}

Если ваш текущий 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>

Выше описан 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));
}

Теперь в моем собственном файле класса Я могу добавить новый частичный класс (новый файл .cs) в правильное пространство имен, которое более удобно раскрывает метод:

namespace MyNamespace {
    partial class MyDataContext
    {
        public int Foo(int? inc, string dataSet)
        {
            return FooPrivate(inc, dataSet).Single().value;
        }
    }
}

(имена пространств и контекстов должны совпадать с фактическим контекстом данных). Это добавляет публичный метод, который скрывает шероховатые детали от вызывающей стороны.

Не редактировать файл designer.cs напрямую; ваши изменения будут потеряны. Редактируйте только dbml или частичные классы.

5 голосов
/ 07 декабря 2010

RETURN @VALUE как последнее утверждение процедуры.

тогда он автоматически определит тип int, string, bool и т. Д. И сгенерирует метод-обертку соответственно.

0 голосов
/ 30 марта 2013

Если вы используете .xsd файл Visual Studio в проекте классов Linq to SQL, убедитесь, что вы:

  1. Щелкните правой кнопкой мыши хранимую процедуру или вызов функции в адаптере.
  2. Выбрать свойства
  3. Изменить режим выполнения на Скалярный

Это заставит вашу функцию адаптера возвращать тип «Объект». Затем вам нужно привести его к типу int или string или к какому-либо другому типу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...