valor tabla que procedimientos procedimiento ejemplo devuelven devolver consultar consulta condiciones condicionales como almacenados almacenado c# linq-to-sql

c# - tabla - procedimiento almacenado sql server ejemplo



LINQ-to-SQL: ¿Procedimiento almacenado que devuelve un único valor escalar? (3)

Estoy usando LINQ-to-SQL para una aplicación que consulta una base de datos heredada. Necesito llamar a un procedimiento almacenado, que selecciona un único valor entero. Cambiar el procedimiento almacenado no es una opción.

El diseñador crea un método con esta firma:

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

Me gustaría que el tipo de devolución sea int. ¿Cómo hago esto usando LINQ-to-SQL?


Esto sería trivial con una función escalar (UDF) en lugar de un SP. Sin embargo, debería funcionar con la suficiente facilidad, aunque si el SP es complejo (es decir, FMT_ONLY no puede inspeccionarlo al 100%), es posible que deba "ayudarlo" ...

Aquí hay algunos dbml que generé de un SP simplfied que devuelve un entero; Puede editar el dbml a través de "abrir con ... editor 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>

(tenga en cuenta que obviamente necesita modificar los nombres y tipos de datos).

Y aquí está el C # generado:

[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)); }

Si su SP actual utiliza SELECT (en lugar de RETURN), entonces el DBML deberá reflejar esto. Puede solucionar esto ocultando los detalles de implementación y proporcionando un contenedor público en una clase parcial; por ejemplo:

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

Lo anterior describe un SP que devuelve una sola tabla con una sola columna; pero he hecho que el SP sea "privado" para el contexto de datos, y el resultado sea "interno" para el ensamblaje (lo oculté):

[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)); }

Ahora en mi propio archivo de clase puedo agregar una nueva clase parcial (un nuevo archivo .cs) en el espacio de nombres correcto, que expone el método de manera más conveniente:

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

(el nombre de espacio y los nombres de contexto deben ser los mismos que el contexto de datos real). Esto agrega un método público que oculta los detalles grungy de la persona que llama.

No edite el archivo designer.cs directamente; tus cambios se perderán Solo edite el dbml o las clases parciales.


RETURN @VALUE como la última instrucción del proceso.

luego detectará automáticamente el tipo int, string, bool, etc. y generará el método de envoltura en consecuencia.


Si está utilizando el archivo .xsd de Visual Studio en un proyecto de clases de Linq a SQL, asegúrese de:

  1. Haga clic con el botón derecho en el procedimiento almacenado o llame a la función en el Adaptador.
  2. Seleccionar propiedades
  3. Cambiar el modo de ejecución a escalar

Eso hará que su función de adaptador vuelva a ser "Objeto". Luego debes convertirlo a int o string, o al tipo que sea.