Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Übergeben Sie den Tabellenwerttyp über Entity Framework an die gespeicherte SQL Server-Prozedur

Angenommen, Sie möchten eine Tabelle mit einer einzelnen Spalte von GUIDs senden.

Zuerst müssen wir eine Struktur mit SqlMetaData die das Schema der Tabelle (Spalten) darstellt.

Der folgende Code zeigt, dass eine Spalte mit dem Namen „Id“ der GUID der Parametertabellentyp für gespeicherte SQL-Prozeduren ist

var tableSchema = new List<SqlMetaData>(1)
{
  new SqlMetaData("Id", SqlDbType.UniqueIdentifier)
}.ToArray();

Als Nächstes erstellen Sie mithilfe von SqlDataRecord .

Der folgende Code zeigt, wie die Elemente in einer Liste mithilfe des oben erstellten Schemas hinzugefügt werden. Erstellen Sie für jedes Element in der Liste einen neuen SqlDataRecord. Ersetzen Sie SetGuid durch den entsprechenden Typ und ersetzen Sie Guid.NewGuid() durch den entsprechenden Wert. Wiederholen Sie den neuen SqlDataRecord für jedes Element und fügen Sie sie einer Liste hinzu

var tableRow = new SqlDataRecord(tableSchema);
tableRow.SetGuid(0, Guid.NewGuid());
var table = new List<SqlDataRecord>(1)
{
  tableRow
};

Erstellen Sie dann den SqlParameter :

var parameter = new SqlParameter();
parameter.SqlDbType = SqlDbType.Structured;
parameter.ParameterName = "@UserIds"; //@UserIds is the stored procedure parameter name
parameter.TypeName = "{Your stored procedure type name}"
parameter.Value = table;

var parameters = new SqlParameter[1]
{
  parameter
};

Rufen Sie dann einfach die gespeicherte Prozedur mithilfe der Datenbank auf .SqlQuery .

IEnumerable<ReturnType> result;
using (var myContext = new DbContext())
{
  result = myContext.Database.SqlQuery<User>("GetUsers @UserIds", parameters)
    .ToList();         // calls the stored procedure
    // ToListAsync();  // Async
{

Erstellen Sie in SQL Server Ihren benutzerdefinierten Tabellentyp (ich setze ihnen das Suffix TTV, Table Typed Value):

CREATE TYPE [dbo].[UniqueidentifiersTTV] AS TABLE(
  [Id] [uniqueidentifier] NOT NULL
)
GO

Geben Sie dann den Typ als Parameter an (nicht vergessen, Tabellentypwerte müssen schreibgeschützt sein!):

CREATE PROCEDURE [dbo].[GetUsers] (
  @UserIds [UniqueidentifiersTTV] READONLY
) AS
BEGIN
  SET NOCOUNT ON

  SELECT u.* -- Just an example :P
  FROM [dbo].[Users] u
  INNER JOIN @UserIds ids On u.Id = ids.Id
END