Comment utiliser DbContext.La base de données.SqlQuery (sql, params) avec procédure stockée? Code EF premier CTP5
j'ai une procédure stockée qui a trois paramètres et j'ai essayé d'utiliser les éléments suivants pour retourner les résultats:
context.Database.SqlQuery<myEntityType>("mySpName", param1, param2, param3);
au début j'ai essayé d'utiliser SqlParameter
objets comme les params mais cela n'a pas fonctionné et a jeté un SqlException
avec le message suivant:
procédure ou fonction ' mySpName 'attend le paramètre' @param1', qui n'a pas été fourni.
donc ma question Est comment vous pouvez utiliser cette méthode avec une procédure stockée qui attend les paramètres?
Merci.
10 réponses
vous devez fournir les instances SqlParameter de la manière suivante:
context.Database.SqlQuery<myEntityType>(
"mySpName @param1, @param2, @param3",
new SqlParameter("param1", param1),
new SqlParameter("param2", param2),
new SqlParameter("param3", param3)
);
vous pouvez aussi utiliser le paramètre" sql "comme spécificateur de format:
context.Database.SqlQuery<MyEntityType>("mySpName @param1 = {0}", param1)
Cette solution est (seulement) pour SQL Server 2005
vous êtes des sauveurs de vie, mais comme @Dan Mork l'a dit, vous devez ajouter EXEC au mélange. Ce qui me faisait trébucher était:
- "EXEC" avant le nom Proc
- les Virgules entre les Params
- coupant ' @ ' sur le Param Définitions (pas sûr que bits est requis).
:
context.Database.SqlQuery<EntityType>(
"EXEC ProcName @param1, @param2",
new SqlParameter("param1", param1),
new SqlParameter("param2", param2)
);
return context.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
new object[] { param1, param2, param3 });
//Ou
using(var context = new MyDataContext())
{
return context.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
new object[] { param1, param2, param3 }).ToList();
}
//Ou
using(var context = new MyDataContext())
{
object[] parameters = { param1, param2, param3 };
return context.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
parameters).ToList();
}
//Ou
using(var context = new MyDataContext())
{
return context.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
param1, param2, param3).ToList();
}
la plupart des réponses sont fragiles parce qu'elles reposent sur l'ordre des paramètres de la PS. Mieux, le nom de la procédure Stockée paramètres et de donner des valeurs paramétrées.
afin d'utiliser Named params lors de l'appel de votre SP, sans se soucier de l'ordre des paramètres
utilisant des paramètres nommés SQL Server avec ExecuteStoreQuery et Executesorecommand
décrit la meilleure approche. Mieux que la réponse de Dan Mork.
- ne dépend pas de chaînes concaténantes, ni de l'ordre des paramètres définis dans la SP.
E. G.:
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)
j'utilise cette méthode:
var results = this.Database.SqlQuery<yourEntity>("EXEC [ent].[GetNextExportJob] {0}", ProcessorID);
j'aime ça parce que je me contente de déposer des Guids et Datetimes et SqlQuery effectue tout le formatage pour moi.
la réponse de @Tom Halladay est correcte avec la mention que vous shopuld aussi vérifier pour les valeurs nulles et envoyer DbNullable si les params sont nulles que vous obtiendriez une exception comme
de La requête paramétrée '...'attend le paramètre '@parameterName", qui n'a pas été fourni.
quelque chose comme ça m'a aidé
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;
}
(le crédit pour la méthode va à https://stackoverflow.com/users/284240/tim-schmelter )
alors utilisez-le comme:
new SqlParameter("@parameterName", parameter.GetValueOrDbNull())
ou une autre solution, plus simple, mais pas le générique serait:
new SqlParameter("@parameterName", parameter??(object)DBNull.Value)
db.Database.SqlQuery<myEntityType>("exec GetNewSeqOfFoodServing @p0,@p1,@p2 ", foods_WEIGHT.NDB_No, HLP.CuntryID, HLP.ClientID).Single()
@p0,@p1,@p2......
ou
db.Database.SqlQuery<myEntityType>(
"exec GetNewSeqOfFoodServing @param1, @param2",
new SqlParameter("param1", param1),
new SqlParameter("param2", param2)
);
ou
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)
ou
db.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
new object[] { param1, param2, param3 }).ToList();
j'ai eu le même message d'erreur quand je travaillais avec l'appel d'une procédure stockée qui prend deux paramètres d'entrée et retourne 3 valeurs en utilisant L'instruction SELECT et j'ai résolu le problème comme ci-dessous dans la première approche EF Code
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; }
}
UPDATE : on dirait qu'avec SQL SERVER 2005 mot-clé manquant EXEC crée un problème. Donc, pour lui permettre de fonctionner avec toutes les versions de SQL SERVER, j'ai mis à jour ma réponse et ajouté EXEC dans au-dessous de la ligne
List<Sample> x = this.Database.SqlQuery<Sample>(" EXEC usp_NextNumberBOGetMulti @TableName, @FieldName", parameters).ToList();
entityobject_name.Database.ExecuteSqlCommand(string.Format(@"EXEC sp_name @parameter1='{0}',@path='{2}'", pvalue1, pvalue2));
où entityobject_name
est votre objet créé pour entité
exemple: Entity ent=new entity() // ent is entityobject name here