webentwicklung-frage-antwort-db.com.de

Wie verwende ich DbContext.Database.SqlQuery <TElement> (sql, params) mit einer gespeicherten Prozedur? EF Code First CTP5

Ich habe eine gespeicherte Prozedur mit drei Parametern und ich habe versucht, die folgenden zu verwenden, um die Ergebnisse zurückzugeben:

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

Zuerst habe ich versucht, SqlParameter -Objekte als Parameter zu verwenden, aber das hat nicht funktioniert und habe ein SqlException mit der folgenden Meldung geworfen:

Die Prozedur oder Funktion 'mySpName' erwartet den Parameter '@ param1', der nicht angegeben wurde.

Meine Frage ist also, wie Sie diese Methode mit einer gespeicherten Prozedur verwenden können, die Parameter erwartet?

Vielen Dank.

234
electricsheep

Sie sollten die SqlParameter-Instanzen folgendermaßen bereitstellen:

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

Sie können den Parameter "sql" auch als Formatbezeichner verwenden:

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

Diese Lösung ist (nur) für SQL Server 2005

Ihr seid Lebensretter, aber wie @Dan Mork sagte, müsst ihr EXEC zum Mix hinzufügen. Was mich auslöste, war:

  • 'EXEC' vor dem Proc-Namen
  • Kommas zwischen Params
  • Setzen Sie bei den Param-Definitionen ein Häkchen vor '@' (nicht sicher, ob dieses Bit erforderlich ist).

:

context.Database.SqlQuery<EntityType>(
    "EXEC ProcName @param1, @param2", 
    new SqlParameter("param1", param1), 
    new SqlParameter("param2", param2)
);
71
Tom Halladay
return context.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
new object[] { param1, param2, param3 });

//Oder

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

//Oder

using(var context = new MyDataContext())
{
object[] parameters =  { param1, param2, param3 };

return context.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
parameters).ToList();
}

//Oder

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

Die meisten Antworten sind spröde, weil sie von der Reihenfolge der SP-Parameter abhängen. Es ist besser, die Parameter des Stored Proc zu benennen und diesen parametrisierte Werte zuzuweisen.

Damit Sie beim Aufrufen Ihres SP Named-Parameter verwenden können, ohne sich Gedanken über die Reihenfolge der Parameter zu machen

Verwenden von benannten SQL Server-Parametern mit ExecuteStoreQuery und ExecuteStoreCommand

Beschreibt den besten Ansatz. Besser als die Antwort von Dan Mork.

  • Verlässt sich nicht auf die Verkettung von Zeichenfolgen und nicht auf die Reihenfolge der im SP definierten Parameter.

Z.B.:

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)
5
Don Cheadle
db.Database.SqlQuery<myEntityType>("exec GetNewSeqOfFoodServing @p0,@p1,@p2 ", foods_WEIGHT.NDB_No, HLP.CuntryID, HLP.ClientID).Single()

oder

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

oder

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)

oder

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

Ich benutze diese Methode:

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

Ich mag es, weil ich einfach Guids und Datetimes einlege und SqlQuery die gesamte Formatierung für mich durchführt.

2
Malcolm O'Hare

Die Antwort von @Tom Halladay ist richtig, mit der Erwähnung, dass Sie auch auf Nullwerte prüfen und DbNullable senden sollten, wenn die Parameter Null sind, da Sie eine Ausnahme wie erhalten würden

Die parametrisierte Abfrage '...' erwartet den Parameter '@parameterName', der nicht angegeben wurde.

So etwas hat mir geholfen

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;
}

(Gutschrift für die Methode geht an https://stackoverflow.com/users/284240/tim-schmelter )

Dann benutze es wie folgt:

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

oder eine andere, einfachere, aber nicht generische Lösung wäre:

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

Ich hatte dieselbe Fehlermeldung beim Aufrufen einer gespeicherten Prozedur, die zwei Eingabeparameter verwendet und mit der SELECT-Anweisung 3 Werte zurückgibt, und löste das Problem wie unten in 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 : Es sieht so aus, als würde bei SQL SERVER 2005 ein fehlendes EXEC-Schlüsselwort ein Problem verursachen. Damit es mit allen SQL-SERVER-Versionen funktioniert, habe ich meine Antwort aktualisiert und in der folgenden Zeile EXEC hinzugefügt

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