Esto sería trivial con una función escalar (UDF) en lugar de un SP. Sin embargo, debería funcionar con bastante facilidad, aunque si el SP es complejo (es decir, FMT_ONLY no puede inspeccionarlo al 100%), es posible que necesite "ayudarlo" ...
Aquí hay algunos dbml que generé de un simplfied SP que devuelve un entero; puede editar el dbml vía "abierta editor con ... 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, tiene que modificar los nombres y tipos de datos)
y aquí está la generada 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));
}
Si el SP actual utiliza SELECT (en lugar de RETURN), entonces el DBML tendrá que reflejar esto se puede solucionar este problema al ocultar los detalles de implementación, y proporcionar un envoltorio 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 me he tomado la SP "privado" a los datos de contexto, y el tipo de resultado "interno" a la asamblea (ocultarlo):
[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 añadir una nueva clase parcial (un nuevo archivo .cs) en el espacio de nombre correcto que expone el método más conveniente:
namespace MyNamespace {
partial class MyDataContext
{
public int Foo(int? inc, string dataSet)
{
return FooPrivate(inc, dataSet).Single().value;
}
}
}
(el espacio de nombres y nombres de contexto tienen que ser los mismos que los datos del contexto 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.
Exactamente lo que estaba buscando. Gracias. – driis
@driss - si tiene problemas con SELECT, hágamelo saber –
He utilizado la misma técnica en mi proyecto anteriormente. Funciona muy bien ... Hasta que edites tu DBML en el editor de alguna manera. Todos sus cambios serán sobrescritos. Solía guardar un archivo xml separado cada vez que hacía modificaciones manuales, pero espero que haya una manera mejor de alguna manera. –