Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Passer le type de valeur de table à la procédure stockée SQL Server via Entity Framework

Supposons que vous souhaitiez envoyer une table avec une seule colonne de GUID.

Nous devons d'abord créer une structure en utilisant SqlMetaData qui représente le schéma du tableau (colonnes).

Le code ci-dessous montre qu'une colonne nommée "Id" du GUID est le type de table de paramètres de procédure stockée SQL

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

Ensuite, vous créez une liste d'enregistrements qui correspondent au schéma en utilisant SqlDataRecord .

Le code ci-dessous montre comment ajouter les éléments dans une liste en utilisant le schéma créé ci-dessus. Créez un nouveau SqlDataRecord pour chacun des éléments de la liste. Remplacez SetGuid par le type correspondant et remplacez Guid.NewGuid() comme valeur correspondante. Répétez le nouveau SqlDataRecord pour chaque élément et ajoutez-les à une liste

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

Créez ensuite le 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
};

Ensuite, appelez simplement la procédure stockée en utilisant la 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
{

Dans SQL Server, créez votre type de table défini par l'utilisateur (je les suffixe avec TTV, Table Typed Value):

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

Spécifiez ensuite le type en tant que paramètre (n'oubliez pas que les valeurs de type de table doivent être en lecture seule !) :

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