2010-09-29 24 views
5

Estoy utilizando Entity Framework 4 con el generador de código POCO. Tengo un procedimiento almacenado que hace un INSERT y devuelve @@ IDENTITY del registro insertado. Estoy tratando de importar el procedimiento almacenado como una función en mi archivo .edmx, pero estoy teniendo problemas para usarlo.Entidad Framework 4 Función Importación no funciona

En el navegador de modelos, puedo ver el procedimiento almacenado en la jerarquía de la base de datos, y luego hago clic derecho y selecciono "Función de importación ..." He intentado usar "Ninguno" como el tipo de retorno e Int32 (a pesar de que dice "Colección de ..."). La función aparece en Importaciones de funciones, pero incluso después de guardar y compilar, no puedo encontrar la función en ningún lugar en mi ObjectContext. Intenté eliminarlo y volver a importar el procedimiento almacenado varias veces sin éxito.

NOTA: Tengo otro procedimiento almacenado que hace un SELECT directo y esto se importa correctamente y aparece en el código ObjectContext.

¿Estoy haciendo algo mal?

Respuesta

5

Si su procedimiento almacenado no devuelve un conjunto de resultados, entonces selecciona "Devuelve una colección de" "Ninguno" en el cuadro de diálogo "Agregar importación de función" en Visual Studio, entonces la importación de funciones NO se agrega como método en su contexto de objeto generado. (Todavía no he podido averiguar por qué, pero sigo buscando)

El valor de retorno de sproc (por ejemplo, return @@ identity) no es lo que significa "Devuelve una colección de "pregunta. Por eso no funcionó. La pregunta es preguntar qué resultado se obtiene del sproc.

Hay tres maneras en que puedo pensar para manejar su problema:

  1. devolver su valor de identidad utilizando una selección (por ejemplo, select @@ identidad como identidad) y especifique una colección de Int32 en respuesta a la pregunta "Devuelve una colección de".

  2. devolver su valor de identidad mediante una cláusula de salida en su estado de inserción y hacerlo de la misma manera como en 1.

  3. uso de Entity SQL y crea el valor de identidad un parámetro de salida. Aquí es cómo hacerlo: How to: Execute a Query Using a Stored Procedure with In and Out Parameters

Espero que ayude.

5

En la investigación del archivo POCO .Context.tt He encontrado el código siguiente en torno a la línea 111

if (edmFunction.ReturnParameter == null) 
{ 
    continue; 
} 
string returnTypeElement = code.Escape(ef.GetElementType(edmFunction.ReturnParameter.TypeUsage)); 

lo que significa que cualquier importación de funciones que devuelven 'ninguno' no se escribirá.

he modificado mi archivo .Context.tt de manera que el código anterior se reemplaza con

string returnTypeElement = @""; 
if (edmFunction.ReturnParameter == null) 
{ 
    returnTypeElement = @"void"; 
} else { 
    returnTypeElement = code.Escape(ef.GetElementType(edmFunction.ReturnParameter.TypeUsage)); 
} 

entonces he tenido que añadir algunas comprobaciones en torno a la declaración de la función (alrededor de la línea 118)

<# 
    if(returnTypeElement != "void"){ 
#> 
    <#=Accessibility.ForMethod(edmFunction)#> ObjectResult<<#=returnTypeElement#>> <#=code.Escape(edmFunction)#>(<#=paramList#>) 
<# 
    } else { 
#> 
    <#=Accessibility.ForMethod(edmFunction)#> <#=returnTypeElement#> <#=code.Escape(edmFunction)#>(<#=paramList#>) 
<# 
    } 
#> 

y la declaración de devolución (alrededor de la línea 142)

<# 
    if(returnTypeElement != "void"){ 
#> 
     return base.ExecuteFunction<<#=returnTypeElement#>>("<#=edmFunction.Name#>"<#=code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()))#>); 
<# 
    } else { 
#> 
     base.ExecuteFunction("<#=edmFunction.Name#>"<#=code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()))#>); 
<# 
    } 
#> 

Ahora, esto podría ¡No será la solución más elegante (cadenas de código rígido!), pero sí significa que puedo usar la función de importación en mis procedimientos almacenados que no devuelven nada y tienen las funciones correspondientes creadas en el archivo .Context.cs y, por lo tanto, accesibles a través de Intellisense.

+0

Bien hecho - ¡funciona bien! – BrianCooksey

Cuestiones relacionadas