Compartir a través de


Entity Framework FAQ Procedimientos Almacenados y Funciones (es-ES)

 Volver a EF FAQ tabla de contenido

  

Este artículo está disponible en otros idiomas:
  • [[articles:(Entity Framework FAQ) Sprocs and Functions|Inglés]]

¿Pueden procedimientos almacenados devolver resultados polimórficos?

Sí, los procedimientos almacenados que recuperan instancias de entidades pueden devolver resultados polimórficos en lugar de limitarse sólo a resultados de un solo tipo.

¿Cómo puedo utilizar los procedimientos almacenados que devuelven sólo tipos simples?

EF 4 soporta procedimientos almacenados que devuelven colecciones de escalares, tipos complejos, y entidades. Así que para los procedimientos almacenados en que participan valores escalares, EF anticipa que devolverán una colección de valores escalares en lugar de sólo uno. Vea ejemplos en MSDN: Cómo: ejecutar una consulta mediante un procedimiento almacenado con parámetros de entrada y salida  y devtoolshed.com: using-stored-procedures-entity-framework-scalar-return-values .

Para los procedimientos almacenados de lectura EF 3.5 SP1 sólo admite los que devuelven las entidades. En este caso, puede utilizar ADO.NET clásico para realizar sus tareas, y porque el EF expone la conexión de base de datos subyacente, es relativamente sencillo integrar este tipo de código con otro código basado en EF. Este proceso se hace aún más simple con la adición de la biblioteca de EFExtensions, que se encuentra en: http://code.msdn.microsoft.com/EFExtensions . Con la biblioteca de EFExtensions podría añadir un método parcial a su contexto que llamaría el procedimiento almacenado con el código que se ve algo como esto:

public int callMySproc()
{ DbCommand command = this.CreateStoreCommand("MySproc",
 CommandType.StoredProcedure);
int result;
using (this.Connection.CreateConnectionScope())
{
result = command.ExecuteNonQuery();
}
return result;
}

Si el procedimiento almacenado devuelve un valor único, tienes que utilizar uno de los métodos que extraen un único valor de una colección, por ejemplo FirstOrDefault().

¿Entity Framework admite la posibilidad de tener un único procedimiento almacenado que devuelve varios conjuntos de resultados?

Entity Framework no tienen soporte para devolver conjuntos de resultados múltiples de una único procedimiento almacenado. Sin embargo, hay una manera de leer conjuntos de resultados múltiples usando el método Translate de ObjectContext que fue agregado en Entity Framework 4. Para realizar esta tarea debe leer los datos utilizando ADO.NET. Para hacer esto, se crea los objetos SqlConnection y SqlCommand, y establece que el texto del comando sea igual al nombre del procedimiento almacenado y, a continuación, llamando a ExecuteReader para obtener el DataReader. A continuación, puede utilizar el método Translate para materializar los objetos de entidad desde el DataReader. El método Translate requiere un DataReader, el nombre de un conjunto de entidades, y una opción de combinación. Tenga en cuenta que si desea agregar los objetos materializados al contexto, para que pueden ser seguidos y sincronizados con sus objetos relacionados, es necesario utilizar MergeOption.AppendOnly. En el ejemplo siguiente se muestra cómo hacerlo:

using (var context =  new SchoolEntities())
{
 string providerString = @"Data Source=.;Initial Catalog=School;Integrated Security=True";
using (var conn = new SqlConnection(providerString))
{
var cmd = conn.CreateCommand();
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.CommandText = "GetStudentGrades";
cmd.Parameters.AddWithValue("StudentID", 2);
conn.Open();
var reader = cmd.ExecuteReader(
System.Data.CommandBehavior.CloseConnection);
var students = context.Translate<Person>(
reader, "People", MergeOption.AppendOnly).ToList();
reader.NextResult();
context.Translate<StudentGrade>(reader,
 "StudentGrades", MergeOption.AppendOnly) .ToList();
 foreach(var student  in students)
{
foreach (var grade  in student.StudentGrades)
{
Console.WriteLine(grade.Grade);
}
}
}
}

Véase también este post .

¿Cómo ejecuto una consulta mediante un procedimiento almacenado con parámetros de salida?

Procedimientos almacenados que devuelven resultados no rellenan los parámetros de salida hasta después de que todos los resultados de los procedimientos almacenados se han leído. Por lo tanto tienes dos alternativas:

  • Si estás interesado en los resultados, tienes que iterarlos completamente.
  • Si no necesitas los resultados, simplemente puede llamar a Dispose().

Para más información, consulte Cómo: ejecutar una consulta mediante un procedimiento almacenado con parámetros de entrada y salida  .

¿Cómo llamo un procedimiento almacenado cuando se utiliza el método ExecuteStoreCommand?

ExecuteStoreCommand fue diseñado para soportar declaraciones de SQL arbitraria, tal como INSERT, UPDATE, DELETE, y SELECT. También se puede utilizar para acciones como la configuración de nivel de aislamiento (por ejemplo, SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED). Por lo tanto, el CommandType de la DCommand se establece en CommandType.Text en lugar de CommandType.StoredProcedure. Por esa razón que es necesario especificar la sintaxis completa para invocar el procedimiento almacenado, incluyendo el modificador "OUT" para los parámetros de salida que desea obtener sus valores, así:

contexto de context.ExecuteStoreCommand("EXEC StoredProcedure1 @param1, @param2 OUT", 
 storeParams);

Importación de función para procedimientos almacenados sin resultados utiliza la sobrecarga de ExecuteFunction que devuelve un int que informe que filas fueron afectadas. ¿Por qué la función devuelve -1 aunque sé cuales filas fueron afectadas?

Asegúrese de que la propiedad SET NOCOUNT en SQL Server es OFF. Si se establece en ON, el número de filas afectadas por una instrucción de Transact-SQL no se devolverá como parte de los resultados.

¿Cómo puedo definir funciones personalizadas (también llamadas funciones definidas por el usuario o funciones definidas por el modelo o MDFs) en el modelo conceptual?

Entity Framework permite definir funciones personalizadas en el modelo conceptual. Estas funciones están escritas en Entity SQL. Puede utilizar estas funciones en las declaraciones Entity SQL o LINQ o de otras funciones definidas por modelo. MDFs pueden devolver valores escalares, tipos anónimos, tipos complejos o colecciones de referencias a entidades. Funciones definidas por el modelo están extensible y pueden utilizarse como bloques de construcción en expresiones más complejas. Para definir una función, es necesario editar manualmente el archivo .edmx. Consulte el tema siguiente para obtener más información: Cómo: definir funciones de medida en el modelo Conceptual .

El siguiente es un ejemplo de una función definida por el modelo que devuelve una colección de objetos de entidad:

<FunctionName="GetStudentGradesMDF" ReturnType="Collection(SchoolModel.StudentGrade)" >
<ParameterName="ID" Type="Edm.Int32" / >
<DefiningExpression>
select VALUE sg
 from SchoolEntities.StudentGrades as sg
 where sg.StudentID == ID
</DefiningExpression>
</Function>

El siguiente es un ejemplo de una función definida por el modelo que devuelve una colección de tipos anónimos:

<Function Name="StudentInfo">
 <Parameter Name="PersonID" Type="Edm.Int32"/>
 <ReturnType>
 <CollectionType>
 <RowType>
 <Property Name="FirstName" Type="Edm.String"/>
 <Property Name="Grade" Type="Edm.Decimal"/>
 </RowType>
 </CollectionType>
 </ReturnType>
 <DefiningExpression>
 select sg.Person.FirstName, sg.Grade 
 from SchoolEntities.StudentGrades as sg 
 where sg.Person.PersonID == PersonID
 </DefiningExpression>
</Function>

Asimismo, consulte los siguientes artículos:

¿Es posible llamar a funciones definidas por el modelo en las consultas LINQ?

Sí. Ver Cómo: llamar a funciones definidas por el modelo (LINQ to Entities) .

Volver a EF FAQ tabla de contenido