Partilhar 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 que ofereça suporte a 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-ins e habilita fontes de dados de tabela virtual para criar a tabela virtual.

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

Detalhes da origem 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(s) tabela(s) ou coluna(s).

Nome da Coluna Tipo de dados Propósito
TicketID Chave primária identificada única Chave primária para a tabela.
Severity Número inteiro Valor de gravidade para o ticket.
Nome String Descrição da permissão.

Há quatro etapas para permitir que um provedor de dados personalizado crie uma tabela virtual.

Passo 1: Implementar plug-ins CRUD e registar a assemblagem

Etapa 2: Criando o provedor de dados e adicionando plug-ins ao provedor

Etapa 3: Criando uma tabela virtual no ambiente Dataverse

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

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

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

    Assembly 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 seguintes seis arquivos de classe à sua solução. Em cada um dos ficheiros de classe, adicione o seguinte utilizando 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 respeitantes ao seu: Servidor de base de dados, ID de Utilizador, Palavra-passe e nome da tabela que irá usar para criar uma tabela virtual no Dataverse.
    CreatePlugin.cs Essa classe contém código que manipula a operação create 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 seguintes informações importantes 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 que você use o fluxo de autenticação mais seguro disponível. O fluxo de autenticação descrito neste artigo requer um grau muito alto de confiança no aplicativo e acarreta 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 construa a solução. Agora você terá um arquivo assembly (.dll) que você pode usar para registrar em seu ambiente Dataverse. Você encontrará esse arquivo na pasta da solução/bin/diretório Debug .

    Assembly DLL.

  2. Registe a assemblagem usando a Ferramenta de Registo de Plug-ins. Você pode obter o pacote mais recente da Ferramenta de Registro de Plug-ins do NuGet.

  3. Abra a Ferramenta de Registo de Plugins. Você precisa ter privilégios de administração do sistema para registrar o assembly. Selecione CREATE NEW CONNECTION para se conectar ao seu ambiente Dataverse. Selecione a lista pendente Registar e, em seguida, selecione Registar nova assemblagem.

    Registe o novo passo.

  4. Selecione o ficheiro de assemblagem e registe os plug-ins. Certifique-se de que selecionou todos os plug-ins (plug-ins Criar, Atualizar, Eliminar, Obter e RetrieveMultiple).

    Registre nova montagem.

Etapa 2: Criando o provedor de dados e adicionando plug-ins ao provedor

  1. Selecione a lista pendente Registar e, em seguida, selecione Registar Novo Fornecedor 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 pretender criar uma nova solução, selecione a opção NewSolution no menu. 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. Certifique-se de que a fonte de dados faz parte da solução que você criou ou selecionou.

      Observação

      A tabela da origem de dados no Dataverse contém os dados de configuração de um registo de origem de dados a ser transmitido para os plug-ins do fornecedor.

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

    5. Registre o novo provedor de dados.

      Registar o fornecedor de dados.

  3. Na Ferramenta de Registro de Plug-ins, você verá o novo registro da fonte de dados e o provedor de dados associado. Selecionar a origem de dados mostrará os detalhes que incluem os plug-ins e respetivos GUID registados.

    Fornecedor de dados registado.

Etapa 3: Criando uma tabela virtual no ambiente Dataverse

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

  2. Selecione Novo e, em seguida, 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 explorador de soluções, selecione Tabelas (Entidades) e, em seguida, selecione Novo.

  6. Insira os seguintes detalhes:

    Coluna Description
    Fonte de dados Selecione a fonte de dados criada na etapa anterior.
    Nome de exibição Nome da tabela virtual.
    Nome Plural O valor será preenchido automaticamente com base no nome para 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 registo.

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

  9. Selecione Campos para atualizar e criar novas colunas que representem a fonte externa.

  10. Selecione a coluna Chave Primária da 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 é Name.

    Criar 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 new_severity
    Nome Externo Severity
    Requisito de campo Campo Necessário
    Tipo de dados Número Inteiro

    Crie um novo campo de gravidade.

  18. Selecione Salvar e Fechar.

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

Crie um aplicativo controlado por modelo e adicione a tabela virtual ao mapa do site. Em seguida, selecione o formulário principal da tabela virtual e a visualização de campo Avançado. Publique o aplicativo. Para obter mais informações: Crie seu primeiro aplicativo orientado por modelo do zero

Crie um aplicativo controlado por modelo.

Os usuários do aplicativo podem executar operações de leitura, criação, atualização, exclusão usando a tabela virtual 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