Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Passa il tipo di valore della tabella alla stored procedure di SQL Server tramite Entity Framework

Supponiamo che tu voglia inviare una tabella con una singola colonna di GUID.

Per prima cosa dobbiamo creare una struttura usando SqlMetaData che rappresenta lo schema della tabella (colonne).

Il codice seguente mostra che una colonna denominata "Id" del GUID è il tipo di tabella dei parametri della procedura memorizzata SQL

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

Quindi crei un elenco di record che corrispondono allo schema utilizzando SqlDataRecord .

Il codice seguente mostra come aggiungere gli elementi all'interno di un elenco utilizzando lo schema creato sopra. Creare un nuovo SqlDataRecord per ciascuno degli elementi nell'elenco. Sostituisci SetGuid con il tipo corrispondente e Sostituisci Guid.NewGuid() come valore corrispondente. Ripeti il ​​nuovo SqlDataRecord per ogni elemento e aggiungilo a un elenco

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

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

Quindi chiama semplicemente la stored procedure utilizzando il Database .SqlQuery .

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

In SQL Server, crea il tuo tipo di tabella definito dall'utente (io li suffisso con TTV, Valore tipizzato dalla tabella):

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

Quindi specifica il tipo come parametro (non dimenticare che i valori del tipo di tabella devono essere di sola lettura!):

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