Como usar o DbContext.Banco.SQLQuery (SQL, params) com procedimento armazenado? Código EF primeiro CTP5

tenho um procedimento armazenado que tem três parâmetros e tenho tentado usar o seguinte para devolver os resultados:

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

no início tentei usar os objectos SqlParameter como os parâmetros, mas isto não funcionou e lançou um SqlException com a seguinte mensagem:

o procedimento ou função 'mySpName' espera o parâmetro '@param1', que não foi fornecido.

então a minha pergunta é como pode usar este método com um procedimento armazenado que espera parâmetros?

Obrigado.

Author: marc_s, 2011-02-02

10 answers

Deve fornecer as instâncias do SqlParameter da seguinte forma:

context.Database.SqlQuery<myEntityType>(
    "mySpName @param1, @param2, @param3",
    new SqlParameter("param1", param1),
    new SqlParameter("param2", param2),
    new SqlParameter("param3", param3)
);
 344
Author: Devart, 2012-06-26 15:42:29

Também pode usar o parâmetro " sql " como um especificador de formato:

context.Database.SqlQuery<MyEntityType>("mySpName @param1 = {0}", param1)
 122
Author: Dan Mork, 2011-06-19 17:15:16

Esta solução é (apenas) para o servidor SQL 2005

Vocês são Salvadores de vidas, mas como @Dan Mork disse, Vocês precisam adicionar EXEC à mistura. O que me chateava era:

  • 'EXEC' antes do nome Proc
  • vírgulas entre Parmas
  • A cortar ' @ ' no Param Definições (não sei se esse bit é necessário).

:

context.Database.SqlQuery<EntityType>(
    "EXEC ProcName @param1, @param2", 
    new SqlParameter("param1", param1), 
    new SqlParameter("param2", param2)
);
 70
Author: Tom Halladay, 2015-06-02 15:13:34
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();
}
 13
Author: Thulasiram, 2012-10-18 15:13:17

A maioria das respostas são frágeis porque dependem da ordem dos parâmetros da SP. É melhor nomear os parâmetros do Proc armazenados e dar valores parametrizados a esses.

A fim de usar os parâmetros nomeados ao ligar para o seu SP, sem se preocupar com a ordem dos parâmetros

Usar os parâmetros nomeados pelo servidor SQL com o ExecuteStoreQuery e o ExecuteStoreCommand

Descreve a melhor abordagem. Melhor do que a resposta do Dan Mork.

  • não confie em cadeias de concatenação, e não confie na ordem de parâmetros definidos no SP.

Por exemplo:

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)
 3
Author: mmcrae, 2017-09-07 21:35:32

Uso este método:

var results = this.Database.SqlQuery<yourEntity>("EXEC [ent].[GetNextExportJob] {0}", ProcessorID);
Eu gosto porque eu só deixo em guias e Datetimes e SqlQuery realiza toda a formatação para mim.
 2
Author: Malcolm O'Hare, 2012-02-27 15:14:00

A resposta de @ Tom Halladay está correcta, com a menção de que também verificaria os valores nulos e enviaria DbNullable se os parâmetros fossem nulos, dado que obteria uma excepção como

The parameterized query'...'espera o parâmetro '@parameterName', que não foi fornecido.

Uma coisa destas ajudou-me.
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;
}

(o crédito pelo método vai para https://stackoverflow.com/users/284240/tim-schmelter)

Então usa-o. tipo:

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

Ou outra solução, mais simples, mas não genérica seria:

new SqlParameter("@parameterName", parameter??(object)DBNull.Value)
 1
Author: emanuel.virca, 2017-05-23 11:54:41
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();
 1
Author: Hossein Hajizadeh, 2017-10-15 08:02:10

Eu tinha a mesma mensagem de erro quando estava a trabalhar com a chamada de um procedimento armazenado que toma dois parâmetros de entrada e devolve 3 valores usando a instrução SELECT e resolvi o problema como em baixo na primeira abordagem do Código EF

 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 : parece que com o servidor de SQL em falta a palavra-chave EXEC está a criar problemas. Então, para permitir que ele funcione com todas as versões do servidor SQL eu atualizei minha resposta e adicionei EXEC em baixo da Linha

 List<Sample> x = this.Database.SqlQuery<Sample>(" EXEC usp_NextNumberBOGetMulti @TableName, @FieldName", parameters).ToList();
 0
Author: Ziggler, 2015-03-31 18:55:41
entityobject_name.Database.ExecuteSqlCommand(string.Format(@"EXEC sp_name @parameter1='{0}',@path='{2}'", pvalue1, pvalue2));

Onde entityobject_name é o teu objecto criado para entidade exemplo: Entity ent=new entity() // ent is entityobject name here

 -3
Author: Shanmuga priya, 2018-02-05 11:40:51