J'ai une procédure stockée qui a trois paramètres et j'ai essayé d'utiliser les éléments suivants pour renvoyer les résultats:
context.Database.SqlQuery<myEntityType>("mySpName", param1, param2, param3);
Au début, j’ai essayé d’utiliser des objets SqlParameter
comme paramètres mais cela n’a pas fonctionné et jette un SqlException
avec le message suivant:
La procédure ou la fonction 'mySpName' attend le paramètre '@ param1', qui n'a pas été fourni.
Ma question est donc la suivante: comment utiliser cette méthode avec une procédure stockée qui attend des paramètres?
Merci.
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)
);
De plus, vous pouvez utiliser le paramètre "sql" comme spécificateur de format:
context.Database.SqlQuery<MyEntityType>("mySpName @param1 = {0}", param1)
Cette solution est (uniquement) pour SQL Server 2005
Vous êtes des sauveteurs, mais comme l'a dit @Dan Mork, vous devez ajouter EXEC au mélange. Ce qui me faisait trébucher était:
:
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 car elles dépendent de l'ordre des paramètres du SP. Mieux vaut nommer les paramètres de Stored Proc et leur donner des valeurs paramétrées.
Pour utiliser les paramètres nommés lors de l'appel de votre SP, sans vous soucier de l'ordre des paramètres
tilisation de paramètres nommés SQL Server avec ExecuteStoreQuery et ExecuteStoreCommand
Décrit la meilleure approche. Mieux que la réponse de Dan Mork ici.
Par exemple.:
var cmdText = "[DoStuff] @Name = @name_param, @Age = @age_param";
var sqlParams = new[]{
new SqlParameter("name_param", "Josh"),
new SqlParameter("age_param", 45)
};
context.Database.SqlQuery<myEntityType>(cmdText, sqlParams)
db.Database.SqlQuery<myEntityType>("exec GetNewSeqOfFoodServing @p0,@p1,@p2 ", foods_WEIGHT.NDB_No, HLP.CuntryID, HLP.ClientID).Single()
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'utilise cette méthode:
var results = this.Database.SqlQuery<yourEntity>("EXEC [ent].[GetNextExportJob] {0}", ProcessorID);
Je l’aime bien parce que je viens de déposer dans Guids et Datetimes et que SqlQuery effectue tout le formatage pour moi.
La réponse de @Tom Halladay est correcte avec la mention que vous voulez également vérifier les valeurs nulles et envoyer DbNullable si les paramètres sont nuls, comme vous obtiendrez une exception comme
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 non générique serait:
new SqlParameter("@parameterName", parameter??(object)DBNull.Value)
J'avais le même message d'erreur lorsque je travaillais avec l'appel d'une procédure stockée qui prend deux paramètres d'entrée et renvoie 3 valeurs à l'aide de l'instruction SELECT et j'ai résolu le problème comme ci-dessous dans EF Code First Approach
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: Il semble qu'avec SQL SERVER 2005, le mot clé EXEC manquant 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 en dessous de la ligne
List<Sample> x = this.Database.SqlQuery<Sample>(" EXEC usp_NextNumberBOGetMulti @TableName, @FieldName", param).ToList();