Compartilhar via


Exemplo: provedor de tabela virtual personalizado com operações CRUD

Este exemplo mostra como implementar um provedor de dados personalizado para criar uma tabela virtual compatível com operações de criação, recuperação, atualização e exclusão. Para cada uma dessas operações, você implementa um plug-in genérico, registra-os usando a Ferramenta de Registro de Plug-in e habilita fontes de dados de tabela virtual para criar a tabela virtual.

Para saber mais sobre provedores de dados e desenvolvimento de plug-in, consulte provedores de dados personalizados

Detalhes da fonte de dados

Neste passo a passo, você configurará uma tabela simples em um SQL Server externo para criar uma tabela virtual. O nome da tabela usado neste exemplo é VETicket.

Observação

Atualize o código do plug-in, se desejar alterar o nome da tabela ou das colunas.

Nome da Coluna Tipo de Dados Propósito
TicketID Identificador único, chave primária Chave primária para a tabela.
Severity Integer Valor de gravidade do tíquete.
Nome String Descrição do tíquete.

Há quatro etapas para habilitar um provedor de dados personalizado a criar uma tabela virtual.

Etapa 1: Implementando plug-ins CRUD e registrando o assembly

Etapa 2: Criar um provedor de dados e adicionar plug-ins ao provedor

Etapa 3: Criando uma tabela virtual no ambiente do Dataverse

Etapa 4: Criar, atualizar, exibir e excluir registros usando uma tabela virtual

Etapa 1: Implementação de plug-ins CRUD e registro do assembly

  1. Crie seu projeto de plug-in e instale os seguintes pacotes NuGet. A solução neste exemplo se chama StubProvider.

    Assembléia URL
    Microsoft.CrmSdk.CoreAssemblies https://www.nuget.org/packages/Microsoft.CrmSdk.CoreAssemblies
    Microsoft.CrmSdk.Data https://www.nuget.org/packages/Microsoft.CrmSdk.Data
    Microsoft.CrmSdk.Deployment https://www.nuget.org/packages/Microsoft.CrmSdk.Deployment
    Microsoft.CrmSdk.Workflow https://www.nuget.org/packages/Microsoft.CrmSdk.Workflow
    Microsoft.CrmSdk.XrmTooling.CoreAssembly https://www.nuget.org/packages/Microsoft.CrmSdk.XrmTooling.CoreAssembly
    Microsoft.IdentityModel.Clients.ActiveDirectory https://www.nuget.org/packages/Microsoft.IdentityModel.Clients.ActiveDirectory
    Microsoft.Rest.ClientRuntime https://www.nuget.org/packages/Microsoft.Rest.ClientRuntime
    Newtonsoft.Json https://www.nuget.org/packages/Newtonsoft.Json/13.0.1-beta2
  2. Adicione os seis arquivos de classe a seguir à sua solução. Em cada um dos arquivos de classe, adicione o seguinte usando instruções

    using System; 
    using System.Collections.Generic; 
    using System.Data.SqlClient; 
    using System.Linq; using System.Text; 
    using System.Threading.Tasks; 
    using Microsoft.Xrm.Sdk; 
    using Microsoft.Xrm.Sdk.Extensions; 
    using Microsoft.Xrm.Sdk.Data.Exceptions; 
    using Newtonsoft.Json; 
    

    Observação

    Em cada um desses arquivos de classe, atualize o nome da tabela para corresponder ao nome da tabela de origem que você configurou. O exemplo usa VETicket como o nome da tabela de origem.

    Nome do arquivo de classe Propósito
    Connection.cs Essa classe contém código para criar e gerenciar a conexão com a fonte de dados SQL externa. Ele inclui parâmetros de cadeia de conexão específicos para o banco de dados externo e informações de autenticação baseadas em SQL necessárias para estabelecer a conexão. Substitua os valores respectivos do seu servidor de banco de dados, UserID, senha e nome da tabela ao criar uma tabela virtual no Dataverse.
    CreatePlugin.cs Essa classe contém código que manipula a operação de criação para a tabela virtual.
    UpdatePlugin.cs Essa classe contém código que manipula a atualização de registros na tabela virtual.
    RetrievePlugin.cs Essa classe contém código que recupera um registro específico da tabela virtual.
    RetrieveMultiplePlugin.cs Essa classe contém código para buscar vários registros da tabela virtual.
    DeletePlugin.cs Essa classe contém código que permite excluir um registro na tabela virtual.

Leia as informações importantes a seguir sobre como usar uma cadeia de conexão ou autenticação de nome de usuário/senha no código do aplicativo.

Importante

A Microsoft recomenda usar o fluxo de autenticação mais seguro disponível. O fluxo de autenticação descrito neste artigo requer um alto grau de confiança no aplicativo e traz riscos que não estão presentes em outros fluxos. Você só deve usar esse fluxo quando outros fluxos mais seguros, como identidades gerenciadas, não forem viáveis.

Código para Connection.cs

 public static class Connection
{
   public static SqlConnection GetConnection()
   {
       try
       {
           //sample database to connect to 
           SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
           builder.DataSource = "Enter name or network address of the SQL Server";
           builder.UserID = "Enter User Name";
           builder.Password = "Enter password";
           builder.InitialCatalog = "Enter database details";
           SqlConnection connection = new SqlConnection(builder.ConnectionString);
           return connection;
       }
       catch (SqlException e)
       {
           Console.WriteLine(e.ToString());
           throw;
       }
   }
}

Código para CreatePlugin.cs

public class CreatePlugin : IPlugin
{
    public void Execute(IServiceProvider serviceProvider)
    {
        var context = serviceProvider.Get<IPluginExecutionContext>();
        if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
        {
            Entity entity = (Entity)context.InputParameters["Target"];
            Guid id = Guid.NewGuid();
            //change the table name below to the source table name you have created 
            string cmdString = "INSERT INTO VETicket (TicketID,Name,Severity) VALUES (@TicketID, @Name, @Severity)";
            SqlConnection connection = Connection.GetConnection();
            using (SqlCommand command = connection.CreateCommand())
            {
                command.CommandText = cmdString;
                command.Parameters.AddWithValue("@TicketID", id);
                command.Parameters.AddWithValue("@Name", entity["new_name"]);
                command.Parameters.AddWithValue("@Severity", entity["new_severity"]);
                connection.Open();
                try
                {
                    var numRecords = command.ExecuteNonQuery();
                    Console.WriteLine("inserted {0} records", numRecords);
                }
                finally
                {
                    connection.Close();
                }
                // other codes. 
            }
            context.OutputParameters["id"] = id;
        }
    }
}

Código para UpdatePlugin.cs

public class UpdatePlugin: IPlugin {
    public void Execute(IServiceProvider serviceProvider)
    {
        var context = serviceProvider.Get<IPluginExecutionContext>();
        Guid id = Guid.Empty;
        if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
        {
            Entity entity = (Entity)context.InputParameters["Target"];
            //change the table name below to the source table name you have created  
            string cmdString = "UPDATE VETicket SET {0} WHERE TicketID=@TicketID";
            SqlConnection connection = Connection.GetConnection();
            using (SqlCommand command = connection.CreateCommand())
            {
                command.Parameters.AddWithValue("@TicketID", entity["new_ticketid"]);
                List<string> setList = new List<string>();
                if (entity.Attributes.Contains("new_name"))
                {
                    command.Parameters.AddWithValue("@Name", entity["new_name"]);
                    setList.Add("Name=@Name");
                }
                if (entity.Attributes.Contains("new_severity"))
                {
                    command.Parameters.AddWithValue("@Severity", entity["new_severity"]);
                    setList.Add("Severity=@Severity");
                }
                command.CommandText = string.Format(cmdString, string.Join(",", setList)); connection.Open();
                try
                {
                    var numRecords = command.ExecuteNonQuery();
                    Console.WriteLine("updated {0} records", numRecords);
                }
                finally
                {
                    connection.Close();
                }
                // other codes. 
            }
        }
    }
}

Código para RetrievePlugin.cs

public class RetrievePlugin : IPlugin
{
    public void Execute(IServiceProvider serviceProvider)
    {
        var context = serviceProvider.Get<IPluginExecutionContext>();
        Guid id = Guid.Empty;
        if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is EntityReference)
        {
            EntityReference entityRef = (EntityReference)context.InputParameters["Target"];
            Entity e = new Entity("new_ticket");
            //change the table name below to the source table name you have created  
            string cmdString = "SELECT TicketID, Severity, Name FROM VETicket WHERE TicketID=@TicketID";
            SqlConnection connection = Connection.GetConnection();
            using (SqlCommand command = connection.CreateCommand())
            {
                command.CommandText = cmdString;
                command.Parameters.AddWithValue("@TicketID", entityRef.Id);
                connection.Open();
                try
                {
                    using (SqlDataReader reader = command.ExecuteReader())
                    {
                        if (reader.Read())
                        {
                            e.Attributes.Add("new_ticketid", reader.GetGuid(0));
                            e.Attributes.Add("new_severity", reader.GetInt32(1));
                            e.Attributes.Add("new_name", reader.GetString(2));
                        }
                    }
                }
                finally
                {
                    connection.Close();
                }
                // other codes. 
            }
            context.OutputParameters["BusinessEntity"] = e;
        }
    }
}

Código para RetrieveMultiplePlugin.cs

public class RetrieveMultiplePlugin : IPlugin
{
    public void Execute(IServiceProvider serviceProvider)
    {
        var context = serviceProvider.Get<IPluginExecutionContext>();
        EntityCollection collection = new EntityCollection();
        //change the table name below to the source table name you have created  
        string cmdString = "SELECT TicketID, Severity, Name FROM VETicket";
        SqlConnection connection = Connection.GetConnection();
        using (SqlCommand command = connection.CreateCommand())
        {
            command.CommandText = cmdString;
            connection.Open();
            try
            {
                using (SqlDataReader reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        Entity e = new Entity("new_ticket");
                        e.Attributes.Add("new_ticketid", reader.GetGuid(0));
                        e.Attributes.Add("new_severity", reader.GetInt32(1));
                        e.Attributes.Add("new_name", reader.GetString(2));
                        collection.Entities.Add(e);
                    }
                }
            }
            finally
            {
                connection.Close();
            }
            context.OutputParameters["BusinessEntityCollection"] = collection;
        }
    }
}

Código para DeletePlugin.cs

public class DeletePlugin : IPlugin
{
    public void Execute(IServiceProvider serviceProvider)
    {
        var context = serviceProvider.Get<IPluginExecutionContext>();
        //comment 
        Guid id = Guid.Empty;
        if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is EntityReference)
        {
            EntityReference entityRef = (EntityReference)context.InputParameters["Target"];
            id = entityRef.Id;
            //change the table name below to the source table name you have created 
            string cmdString = "DELETE VETicket WHERE TicketID=@TicketID";
            SqlConnection connection = Connection.GetConnection();
            using (SqlCommand command = connection.CreateCommand())
            {
                command.CommandText = cmdString; command.Parameters.AddWithValue("@TicketID", id);
                connection.Open();
                try
                {
                    var numRecords = command.ExecuteNonQuery();
                    Console.WriteLine("deleted {0} records", numRecords);
                }
                finally
                {
                    connection.Close();
                }
                // other codes. 
            }
        }
    }
}
  1. Compile e crie a solução. Agora você terá um arquivo de assembly (.dll) que pode ser usado para se registrar em seu ambiente do Dataverse. Você encontrará esse arquivo no diretório /solution folder/bin/Debug.

    assembly DLL.

  2. Registre o assembly usando a Plugin Registration Tool. Você pode obter o pacote mais recente da Ferramenta de Registro de Plug-in do NuGet.

  3. Abra a Ferramenta de Registro de Plug-in. Você precisa ter privilégios de administração do sistema para registrar o assembly. Selecione CREATE NEW CONNECTION para se conectar ao seu ambiente do Dataverse. Selecione o menu suspenso Registrar e selecione Registrar Novo Assembly.

    Registrar nova etapa.

  4. Selecione o arquivo de assembly e registre os plug-ins. Verifique se você selecionou todos os plug-ins (plug-ins Create, Update, Delete, Retrieve e RetrieveMultiple).

    Registre o novo assembly.

Etapa 2: Criar um provedor de dados e adicionar plug-ins ao provedor

  1. Selecione o menu suspenso Registrar e selecione Registrar Novo Provedor de Dados.

  2. Na caixa de diálogo Registrar Novo Provedor de Dados , insira os seguintes detalhes:

    1. Insira o nome do provedor de dados.

    2. Na opção Soluções , selecione uma solução existente ou crie uma nova solução na lista suspensa. Se você quiser criar uma nova solução, selecione a opção NewSolution na lista suspensa. Na caixa de diálogo Criar Nova Solução , insira os detalhes necessários e selecione Salvar.

    3. Na opção Tabela de Fonte de Dados (Entidade), selecione Criar Nova Fonte de Dados. Insira os detalhes. Verifique se a fonte de dados faz parte da solução que você criou ou selecionou.

      Observação

      A tabela da fonte de dados no Dataverse contém os dados de configuração para um registro da fonte de dados a ser passado para os plug-ins do provedor.

    4. Mapeie cada um dos plug-ins registrados para suas respectivas operações.

    5. Registre o novo provedor de dados.

      Registre o provedor de dados.

  3. Na Ferramenta de Registro do Plug-in, você verá o novo registro da fonte de dados e o provedor de dados associado. Selecionar a fonte de dados exibe os detalhes que incluem os plug-ins e seu GUID registrado.

    Provedor de dados registrado.

Etapa 3: Criando uma tabela virtual no ambiente do Dataverse

  1. Crie uma nova fonte de dados de tabela virtual navegando até Configuração>Administração>Fontes de Dados de Tabela Virtual (Entidade).

  2. Selecione Novo e selecione o provedor de dados que você criou na etapa anterior na lista suspensa.

  3. Insira um nome para a fonte de dados e selecione Salvar e Fechar.

  4. Agora você está pronto para criar a tabela virtual que representa a fonte de dados externa. Para fazer isso, vá para Configurações>Personalizar o Sistema.

  5. No painel de navegação esquerdo do Gerenciador de Soluções, selecione Tabelas (Entidades) e selecione Novo.

  6. Insira os seguintes detalhes:

    Coluna Description
    Fonte de dados Selecione a fonte de dados que você criou na etapa anterior.
    Nome de exibição Nome da tabela virtual.
    Nome no Plural O valor será preenchido automaticamente com base no nome de exibição.
    Nome Isso também será criado automaticamente com base no valor inserido para o nome de exibição.
    Nome Externo O nome da tabela de origem.
    Nome das Coleções Externas Você pode usar o mesmo valor da coluna de nome plural.
  7. Selecione Salvar e Fechar.

    Crie um novo registro.

  8. No painel de navegação esquerdo, selecione e expanda na tabela virtual que você criou.

  9. Selecione Campos para atualizar e criar novas colunas que representam a origem externa.

  10. Selecione a coluna Chave Primária para a tabela virtual e selecione Editar.

  11. Atualize a coluna Nome Externo para corresponder ao nome da coluna na fonte de dados externa. Neste exemplo, o nome da coluna externa é TicketID.

    Crie uma nova tabela.

  12. Selecione Salvar e Fechar.

  13. Selecione o campo Nome da tabela virtual e selecione Editar.

  14. Atualize o campo Nome Externo para corresponder ao nome do campo na fonte de dados externa. Neste exemplo, o nome da coluna externa é Nome.

    Crie um novo campo de nome.

  15. Selecione Salvar e Fechar.

  16. Selecione Novo para criar uma nova coluna na tabela virtual. Esta coluna representará a coluna de severidade na fonte de dados externa.

  17. Insira as seguintes informações para as novas colunas:

    Nome da Coluna Value
    Nome de exibição Severity
    Nome nova_severidade
    Nome Externo Severity
    Requisito do Campo Requisito Comercial
    Tipo de Dados Número Inteiro

    Crie um novo campo de severidade.

  18. Selecione Salvar e Fechar.

Etapa 4: Criar, atualizar, exibir e excluir registros usando uma tabela virtual

Crie um aplicativo controlado por modelos e adicione a tabela virtual ao mapa do site. Em seguida, selecione o formulário principal da tabela virtual e o modo de exibição de campo Avançado. Publique o aplicativo. Mais informações: Crie seu primeiro aplicativo baseado em modelos do zero

Crie um aplicativo controlado por modelos.

Os usuários do aplicativo podem executar operações de leitura, criação, atualização e exclusão usando a tabela virtual, assim como qualquer outra tabela no Microsoft Dataverse.

Consulte também

Introdução às tabelas virtuais
Considerações de API para tabelas virtuais
Provedores de dados de tabela virtual personalizados
Passo a passo da tabela virtual usando o Provedor de Dados OData v4