Benutzer mit den meisten Antworten
Aufruf einer StoredProcedure mit UNIQUEIDENTIFIER-Parametern mittels Entity Framework 6

Frage
-
Hallo zusammen,
ich möchte mit Hilfe des Entity Frameworks 6 eine Stored Procedure (SQL Server 2016) ausführen, die als Suchparameter unter anderem UNIQUEIDENTIFIER akzeptiert. Einer dieser Suchparameter vom Typ UNIQUEIDENTIFIER erwartet genau einen Wert, ein anderer Suchparameter vom Typ NVARCHAR verwendet die übergebenen, kommaseparierten UNIQUEIDENTIFIER-Werte für die IN-Klausel, wobei die Werte vorher mittels STRING_SPLIT gesplittet werden.
Hier ist die auf das Wesentliche gekürzte Stored Procedure:
ALTER PROCEDURE [dbo].[spSearchKontakte] @KontaktstatusId UNIQUEIDENTIFIER = NULL, @KontakttypId NVARCHAR(MAX) = NULL, AS SELECT * FROM Kontakt K LEFT OUTER JOIN AssignedKontakttyp AKT ON K.KontaktId = AKT.KontaktId WHERE (K.KontaktstatusId = @KontaktstatusId OR @KontaktstatusId IS NULL) AND (AKT.KontakttypId IN (SELECT * FROM STRING_SPLIT(@KontakttypId,',')) OR @KontakttypId IS NULL)
Rufe ich die Stored Procedure im SQL Server Management Studio auf, funktioniert alles einwandfrei:
EXEC spSearchKontakte @KontaktstatusId='F64FEDA6-58DB-FC0F-DB32-39E9F660C9BE', @KontakttypId ='C01A0DEB-FFCA-560D-EF7F-39E9FAF87DE8,8C252F95-480C-E38E-F33C-39E9FAF87DE8'
liefert mir korrekte Ergebnisse.Nun wollte ich das Ganze im Entity Framework 6 umsetzen. Dazu habe ich eine Parameterliste vom Typ SQLParameter erzeugt:
Dim parameters As New List(Of SqlParameter) Dim para1 As Guid= "KontaktstatusId" Dim para2 As String = "KontakttypId" parameters.Add(New SqlParameter With {.ParameterName = para1, .DbType = DbType.Guid, .IsNullable = True, .Value = kontaktstatusId}) parameters.Add(New SqlParameter With {.ParameterName = para2, .DbType = DbType.String, .IsNullable = True, .Value = kontakttypIds})
kontaktStatusId ist eine Variable vom Typ Guid und kontakttypIds vom Typ String.
Der Aufruf der Stored Procedure erfolgt mit:
returnList = Database.SqlQuery(Of T)("spSearchKontakte @KontaktstatusId, @KontakttypId", parameters.ToArray).ToList
Der SQL Profiler zeigt, dass diese Anweisung ausgeführt wird:
exec sp_executesql N'EXEC spSearchKontakte @KontaktstatusId, @KontakttypId',N'@KontaktstatusId uniqueidentifier,@KontakttypId nvarchar(73)',@KontaktstatusId='F64FEDA6-58DB-FC0F-DB32-39E9F660C9BE',@KontakttypId=N'c01a0deb-ffca-560d-ef7f-39e9faf87de8,8c252f95-480c-e38e-f33c-39e9faf87de8'
Doch ich erhalte keine Ergebnisse. Weder die Suche nur nach KontaktstatusId, nur nach KontakttypId oder einer Kombination aus beiden findet die entsprechenden Datensätze. returnList.Count ist immer 0.
Zuerst dachte ich, die Ursache liegt in der inneren SELECT-Anweisung (SELECT * FROM STRNG_SPLIT(...), allerdings kann ich das ausschließen. Die komplette Stored Procedure umfasst noch weitere Suchparameter, u.a. vom Typ NVARCHAR. Wenn ich ausschließlich die verwende, funktioniert die Suche auch mittels des EF.
Kann mir bitte jemand von Euch auf die Sprünge helfen?
Vielen Dank und viele Grüße
Michael
- Bearbeitet Bayer, Michael Montag, 12. November 2018 16:25
Antworten
-
Hallo Michael,
das reicht in der Regel auch. Bei benannten Parametern ist die Reihenfolge auch egal.
Ich arbeite in der Regel mit <Parameters>.AddWithValue( ... ), dort habe ich noch keine Probleme feststellen können.
Was mir aber noch an deinem Code aufgefallen ist:
Dim para1 As Guid= "KontaktstatusId" Dim para2 As String = "KontakttypId"
Das dürfte gar nicht laufen, da der Wert für para1 keine Guid ist.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport- Als Antwort vorgeschlagen Ivan DragovMicrosoft contingent staff, Moderator Freitag, 16. November 2018 12:19
- Als Antwort markiert Ivan DragovMicrosoft contingent staff, Moderator Freitag, 23. November 2018 08:10
Alle Antworten
-
Hallo Michael,
wenn ich das nachbaue und die Abfrage, die der Profiler ausgibt, im SSMS gegen Testdaten laufen lasse, funktioniert das problemlos.
Poste doch mal bitte die CREATE TABLE Statements für die beiden Tabellen, INSERT INTO Statements für die Testdaten und passend zu den Testdaten dann das exakte SQL Statement, dass im Profiler ausgegeben wird.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport -
Ich verwende benannte Parameter und war der Meinung, dass es ausreicht, nur die Parameter an die Stored Procedure zu übergeben, die auch einen Wert aufweisen. D.h. alle Parameter mit Wert Nothing/NULL habe ich nicht an die Stored Procedure weitergereicht.
Nachdem ich das geändert habe und sämtliche Parameter an die Stored Procedure weiterreiche, die diese verarbeiten kann - und die .SQLValue-Property bei den nicht benötigten Parametern mit DBNull.Value besetze - funktioniert es. Wichtig ist außerdem, dass die Parameter in derselben Reihenfolge an die Stored Procedure übergeben werden, in der sie dort definiert sind.
Vielen Dank.
Michael
- Bearbeitet Bayer, Michael Dienstag, 13. November 2018 09:40
-
Hallo Michael,
das reicht in der Regel auch. Bei benannten Parametern ist die Reihenfolge auch egal.
Ich arbeite in der Regel mit <Parameters>.AddWithValue( ... ), dort habe ich noch keine Probleme feststellen können.
Was mir aber noch an deinem Code aufgefallen ist:
Dim para1 As Guid= "KontaktstatusId" Dim para2 As String = "KontakttypId"
Das dürfte gar nicht laufen, da der Wert für para1 keine Guid ist.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport- Als Antwort vorgeschlagen Ivan DragovMicrosoft contingent staff, Moderator Freitag, 16. November 2018 12:19
- Als Antwort markiert Ivan DragovMicrosoft contingent staff, Moderator Freitag, 23. November 2018 08:10
-
Hallo Stefan,
vielen Dank für Deine Antworten. <Parameters>.AddWithValue funktioniert beim Entity Framework nicht. Ich mache es jetzt so, wie oben beschrieben. Ist zwar nicht so schön, auch die unbesetzten Parameter mit zu übergeben, aber wenigstens funktioniert es.
Du hast recht - para1 muss vom Typ String sein. War ein Tippfehler.
Viele Grüße
Michael