webentwicklung-frage-antwort-db.com.de

EF ExecuteStoredCommand mit dem Parameter ReturnValue

Ich erstelle eine neue Anwendung, die mit altem Code verbunden werden muss :(.

Die gespeicherte Prozedur, die ich aufrufen möchte, verwendet RETURN für das Ergebnis. Meine Versuche, den Rückgabewert auszuführen und zu verwenden, führen zu einer Ausnahme:

InvalidOperationException: Bei der Ausführung eines Befehls müssen die Parameter ausschließlich Datenbankparameter oder -werte sein.

Das Ändern der gespeicherten Prozedur, um den Wert auf eine andere Weise zurückzugeben, ist nicht erwünscht, da entweder die ältere App aktualisiert werden muss oder eine nahezu doppelt gespeicherte Prozedur gepflegt wird.

Die alte gespeicherte proc-Übersicht:

DECLARE @MyID INT
INSERT INTO MyTable ...
SELECT @MyID = IDENTITY()
RETURN @MyID

My Entity Framework/DbContext funktioniert, was die oben angegebene InvalidOperationException ergibt.

 SqlParameter parm = new SqlParameter() {
    ParameterName = "@MyID",
    Direction = System.Data.ParameterDirection.ReturnValue
 };

 DbContext.Database.ExecuteSqlCommand("EXEC dbo.MyProc", parm);

Suchen Sie nach Lösungen, bei denen die gespeicherte Prozedur nicht geändert werden muss.

16
KDrewiske

Sie können stattdessen den Rückgabewert der gespeicherten Prozedur in einem Ausgabeparameter erfassen:

SqlParameter parm = new SqlParameter() {  
    ParameterName = "@MyID",  
    SqlDbType = SqlDbType.Int,
    Direction = System.Data.ParameterDirection.Output  
 };  

Database.ExecuteSqlCommand("exec @MyId = dbo.MyProc", parm);

int id = (int)parm.Value;
25
Jeff Ogata

Sie haben nicht , um ExecuteSqlCommand zu verwenden.

Sie können die zugrunde liegende Verbindung einfach von DbContext.Database.Connection abrufen und reines ADO.NET verwenden (CreateCommand(), ExecuteNonQuery(), ...).

2
Diego Mijelshon

Ich weiß, dass es etwas spät ist, aber das funktioniert für mich:

var param = new SqlParameter("@Parameter1", txtBoxORsmth.text);

someVariable = ctx.Database.SqlQuery<int>("EXEC dbo.MyProc", param).First();
2
ProToCooL

Die Fehlermeldung

InvalidOperationException: Bei der Ausführung eines Befehls müssen die Parameter ausschließlich Datenbankparameter oder -werte sein.

bedeutet, dass Sie nicht den richtigen Typ (oder etwas anderes, das nicht in Ihrem Code-Snippet angezeigt wird) in der Parameterliste von SQLParameters angeben.

In meinem Fall hatte ich vergessen, eine MergeOption zu entfernen, weil ich die Art und Weise geändert habe, in der der SQL-Befehl ausgeführt wurde.

0
splattne

Ich habe die oben genannten Wege ausprobiert, aber nur dieser Weg klappt für mich (Muss die Funktion 'ToList ()' haben):

 SqlParameter res = new SqlParameter()
        {
            ParameterName = "Count",
            Value=1,
            Direction = System.Data.ParameterDirection.Output
        };
db.Database.SqlQuery<object>(
         "[dbo].[GetWorkerCountBySearchConditions] @Count ,
         res
         ).ToList();
        return Convert.ToInt32(res.Value);
0
Cedric

Diese Erweiterungsmethode erledigt jetzt die ganze schmutzige Arbeit für Sie. Ausführliche Beschreibung zu SO hier .

0

Dies gibt das int aus einer gespeicherten proc mit DBContext zurück:

var newId = DbContext.Database.SqlQuery<int>("EXEC dbo.MyProc @MyID = {0}", parm).First();
0
garethb

Erstellen Sie eine Tabelle für das With-Parameterbeispiel zum Testen oder ändern Sie die zweite SQL-Abfrage entsprechend Ihrer eigenen.

CREATE TABLE [dbo].[Test](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Name] [varchar](50) NOT NULL,
 CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

// ================================================== ========== //

        public void Test()
        {
                  using (var db = new DbContext())
                  {
                      string sql = "dbo.MyProc";  //With Out Parameter

                  int id1 = (int)db.Database.SqlQuery<decimal>(sql).FirstOrDefault();
                  db.SaveChanges();

                  //Or

                  sql = "INSERT Test(Name) values({0}) SELECT SCOPE_IDENTITY();";  //With Parameter
                  int id2 = (int)db.Database.SqlQuery<decimal>(sql, new object[] { "Thulasi Ram.S" }).FirstOrDefault();
                  db.SaveChanges();
              }
        }
0
Thulasiram