2008-11-13 2 views
12

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

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

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

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

ответ

13

Это было бы тривиально со скалярной функцией (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)); 
} 

Если текущий ИП использует 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, который возвращает одну таблицу с одним столбцом; но я сделал СП «личный» в данном контекст, и результат типа «внутренний» в сбор (скрывая его):

[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 или частичные классы.

+0

Именно то, что я искал. Благодарю. – driis 2008-11-13 14:56:18

+0

@driss - если у вас возникли проблемы с SELECT, дайте мне знать – 2008-11-13 14:57:32

5

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

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

0

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

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

Это сделает ваш адаптер возврата функции типа в "Object". Затем вам нужно передать его в int или string, или какой бы тип он ни был.

Смежные вопросы