stored query framework ejecutar c# sql ado.net linq-to-entities entity-framework-ctp5

c# - framework - ¿Cómo usar DbContext.Database.SqlQuery<TElement>(sql, params) con el procedimiento almacenado? Código EF primero CTP5



execute stored procedure in entity framework c# (9)

Tengo un procedimiento almacenado que tiene tres parámetros y he estado tratando de usar lo siguiente para devolver los resultados:

context.Database.SqlQuery<myEntityType>("mySpName", param1, param2, param3);

Al principio intenté usar objetos SqlParameter como parámetros pero esto no funcionó y lancé una SqlException con el siguiente mensaje:

El procedimiento o la función ''mySpName'' esperan el parámetro ''@ param1'', que no se suministró.

Entonces, mi pregunta es ¿cómo puede usar este método con un procedimiento almacenado que espera parámetros?

Gracias.


Además, puede usar el parámetro "sql" como un especificador de formato:

context.Database.SqlQuery<MyEntityType>("mySpName @param1 = {0}", param1)


Debe proporcionar las instancias de SqlParameter de la siguiente manera:

context.Database.SqlQuery<myEntityType>( "mySpName @param1, @param2, @param3", new SqlParameter("param1", param1), new SqlParameter("param2", param2), new SqlParameter("param3", param3) );


La respuesta de @Tom Halladay es correcta con la mención de que también deberías buscar valores nulos y enviar DbNullable si los parámetros son nulos, ya que obtendrías una excepción como

La consulta parametrizada ''...'' espera el parámetro ''@parameterName'', que no se suministró.

Algo como esto me ayudó

public static object GetDBNullOrValue<T>(this T val) { bool isDbNull = true; Type t = typeof(T); if (Nullable.GetUnderlyingType(t) != null) isDbNull = EqualityComparer<T>.Default.Equals(default(T), val); else if (t.IsValueType) isDbNull = false; else isDbNull = val == null; return isDbNull ? DBNull.Value : (object) val; }

(El crédito por el método va a https://.com/users/284240/tim-schmelter )

Entonces úsalo como:

new SqlParameter("@parameterName", parameter.GetValueOrDbNull())

u otra solución, más simple, pero no genérica sería:

new SqlParameter("@parameterName", parameter??(object)DBNull.Value)


Tuve el mismo mensaje de error cuando trabajaba para llamar a un procedimiento almacenado que toma dos parámetros de entrada y devuelve 3 valores con la instrucción SELECT y resolví el problema como se muestra a continuación en el Enfoque del Código EF Primer

SqlParameter @TableName = new SqlParameter() { ParameterName = "@TableName", DbType = DbType.String, Value = "Trans" }; SqlParameter @FieldName = new SqlParameter() { ParameterName = "@FieldName", DbType = DbType.String, Value = "HLTransNbr" }; object[] parameters = new object[] { @TableName, @FieldName }; List<Sample> x = this.Database.SqlQuery<Sample>("EXEC usp_NextNumberBOGetMulti @TableName, @FieldName", parameters).ToList(); public class Sample { public string TableName { get; set; } public string FieldName { get; set; } public int NextNum { get; set; } }

ACTUALIZACIÓN : Parece que con SQL SERVER 2005 falta la palabra clave EXEC está creando problemas. Entonces, para permitir que funcione con todas las versiones del SERVIDOR SQL, actualicé mi respuesta y agregué EXEC en la siguiente línea

List<Sample> x = this.Database.SqlQuery<Sample>(" EXEC usp_NextNumberBOGetMulti @TableName, @FieldName", parameters).ToList();


Yo uso este método:

var results = this.Database.SqlQuery<yourEntity>("EXEC [ent].[GetNextExportJob] {0}", ProcessorID);

Me gusta porque acabo de pasar Guids and Datetimes y SqlQuery realiza todo el formato para mí.


Esta solución es (solo) para SQL Server 2005

Ustedes son salvavidas, pero como dijo @Dan Mork, necesitas agregar EXEC a la mezcla. Lo que me estaba tropezando era:

  • ''EXEC'' antes del Nombre Proc
  • Comas entre params
  • Cortar ''@'' en las definiciones de parámetros (aunque no estoy seguro de que se requiera ese bit).

:

context.Database.SqlQuery<EntityType>( "EXEC ProcName @param1, @param2", new SqlParameter("param1", param1), new SqlParameter("param2", param2) );


La mayoría de las respuestas son frágiles porque dependen del orden de los parámetros del SP. Es mejor nombrar los parámetros de Stored Proc y darles valores parametrizados.

Para utilizar parámetros con nombre al llamar a su SP, sin preocuparse por el orden de los parámetros

Usando los parámetros nombrados de SQL Server con ExecuteStoreQuery y ExecuteStoreCommand

Describe el mejor enfoque. Mejor que la respuesta de Dan Mork aquí.

  • No se basa en concatenar cadenas, y no se basa en el orden de los parámetros definidos en el SP.

P.ej:

var cmdText = "[DoStuff] @Name = @name_param, @Age = @age_param"; var params = new[]{ new SqlParameter("name_param", "Josh"), new SqlParameter("age_param", 45) }; context.Database.SqlQuery<myEntityType>(cmdText, params)


db.Database.SqlQuery<myEntityType>("exec GetNewSeqOfFoodServing @p0,@p1,@p2 ", foods_WEIGHT.NDB_No, HLP.CuntryID, HLP.ClientID).Single()

@ p0, @ p1, @ p2 ......
o

db.Database.SqlQuery<myEntityType>( "exec GetNewSeqOfFoodServing @param1, @param2", new SqlParameter("param1", param1), new SqlParameter("param2", param2) );

o

var cmdText = "exec [DoStuff] @Name = @name_param, @Age = @age_param"; var params = new[]{ new SqlParameter("name_param", "Josh"), new SqlParameter("age_param", 45) }; db.Database.SqlQuery<myEntityType>(cmdText, params)

o

db.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}", new object[] { param1, param2, param3 }).ToList();


return context.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}", new object[] { param1, param2, param3 });

//O

using(var context = new MyDataContext()) { return context.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}", new object[] { param1, param2, param3 }).ToList(); }

//O

using(var context = new MyDataContext()) { object[] parameters = { param1, param2, param3 }; return context.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}", parameters).ToList(); }

//O

using(var context = new MyDataContext()) { return context.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}", param1, param2, param3).ToList(); }