Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Passar o tipo de valor da tabela para o procedimento armazenado do SQL Server por meio do Entity Framework


Digamos que você queira enviar uma tabela com uma única coluna de GUIDs.

Primeiro, precisamos criar uma estrutura usando SqlMetaData que representa o esquema da tabela (colunas).

O código abaixo demonstra que uma coluna chamada "Id" do GUID é o tipo de tabela de parâmetro de procedimento armazenado SQL
var tableSchema = new List<SqlMetaData>(1)
{
  new SqlMetaData("Id", SqlDbType.UniqueIdentifier)
}.ToArray();

Em seguida, você cria uma lista de registros que correspondem ao esquema usando SqlDataRecord .

O código abaixo demonstra como adicionar os itens dentro de uma lista usando o esquema criado acima. Crie um novo SqlDataRecord para cada um dos itens da lista. Substitua SetGuid pelo tipo correspondente e substitua Guid.NewGuid() como o valor correspondente. Repita o novo SqlDataRecord para cada item e adicione-os a uma lista
var tableRow = new SqlDataRecord(tableSchema);
tableRow.SetGuid(0, Guid.NewGuid());
var table = new List<SqlDataRecord>(1)
{
  tableRow
};

Em seguida, crie o 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
};

Em seguida, basta chamar o procedimento armazenado usando o Banco de dados .SqlQuery .
IEnumerable<ReturnType> result;
using (var myContext = new DbContext())
{
  result = myContext.Database.SqlQuery<User>("GetUsers @UserIds", parameters)
    .ToList();         // calls the stored procedure
    // ToListAsync();  // Async
{

No SQL Server, crie seu tipo de tabela definido pelo usuário (eu os sufixo com TTV, valor digitado na tabela):
CREATE TYPE [dbo].[UniqueidentifiersTTV] AS TABLE(
  [Id] [uniqueidentifier] NOT NULL
)
GO

Em seguida, especifique o tipo como um parâmetro (não se esqueça, os valores de tipo de tabela devem ser somente leitura!):
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