Beispiel: Angepasster virtueller Tabellen-Provider mit CRUD-Operationen

Dieses Beispiel zeigt, wie Sie einen angepassten Data Provider implementieren, um eine virtuelle Tabelle zu erstellen, die Create-, Retrieve-, Update- und Delete-Operationen unterstützt. Für jede dieser Operationen implementieren Sie ein generisches Plugin, registrieren es mit dem Plugin Registration Tool und aktivieren die Datenquellen der virtuellen Tabelle, um die virtuelle Tabelle zu erstellen.

Um mehr über Datenanbieter und die Entwicklung von Plugins zu erfahren, lesen Sie Angepasste Datenanbieter

Datenquellendetails

In dieser exemplarischen Vorgehensweise werden Sie eine einfache Tabelle in einem externen SQL Server festlegen, um eine virtuelle Tabelle zu erstellen. Der in diesem Beispiel verwendete Tabellenname ist VETicket.

Hinweis

Aktualisieren Sie Ihren Plugin-Code, wenn Sie den Namen der Tabelle oder der Spalte(n) ändern möchten.

Spaltenname Datentyp Zweck
TicketID Eindeutig identifiziert, Primärschlüssel Primärschlüssel für die Tabelle.
Schweregrad Integer Schweregrad-Wert für das Ticket.
Name des Dataflows String Beschreibung des Tickets.

Es gibt vier Schritte, damit ein angepasster Datenanbieter eine virtuelle Tabelle erstellen kann.

Schritt 1: Implementieren von CRUD-Plug-ins und Registrieren der Assembly

Schritt 2: Erstellen des Data Providers und Hinzufügen von Plug-ins zum Provider

Schritt 3: Erstellen einer virtuellen Tabelle in Dataverse-Umgebung

Schritt 4: Erstellen, Aktualisieren, Anzeigen und Löschen von Datensätzen mit einer virtuellen Tabelle

Schritt 1: Implementieren von CRUD-Plug-ins und Registrieren der Assembly

  1. Erstellen Sie Ihr Plug-In-Projekt und installieren Sie die folgenden NuGet-Pakete. Die Lösung in diesem Beispiel heißt StubProvider.

    Montage 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. Fügen Sie die folgenden sechs Klassendateien zu Ihrer Lösung hinzu. Fügen Sie in jeder der Klassendateien die folgenden using-Anweisungen hinzu

    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; 
    

    Hinweis

    Aktualisieren Sie in jeder dieser Klassendateien den Tabellennamen, damit er mit dem Namen der Quelltabelle übereinstimmt, die Sie eingerichtet haben. Im Beispiel wird VETicket als Quelltabellenname verwendet.

    Name der Klassendatei Zweck
    Connection.cs Diese Klasse enthält Code zum Erstellen und Verwalten der Verbindung zur externen SQL-Datenquelle. Sie enthält Parameter für die Verbindungszeichenfolge, die für die externe Datenbank spezifisch sind, sowie SQL-basierte Authentifizierungsinformationen, die zum Herstellen der Verbindung erforderlich sind. Ersetzen Sie die Werte entsprechend Ihrer: Datenbankserver, UserID, Kennwort und Tabellenname, die Sie eine virtuelle Tabelle erstellen werden, in Dataverse.
    CreatePlugin.cs Diese Klasse enthält Code, der den Erstellungsvorgang für die virtuelle Tabelle abwickelt.
    UpdatePlugin.cs Diese Klasse enthält Code, der das Aktualisieren von Datensätzen in der virtuellen Tabelle behandelt.
    RetrievePlugin.cs Diese Klasse enthält Code, der einen bestimmten Datensatz aus der virtuellen Tabelle abruft.
    RetrieveMultiplePlugin.cs Diese Klasse enthält Code zum Abrufen mehrerer Datensätze aus der virtuellen Tabelle.
    DeletePlugin.cs Diese Klasse enthält Code, der es erlaubt, einen Datensatz in der virtuellen Tabelle zu löschen.

    Code für 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;
           }
       }
    }
    

    Code für 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;
            }
        }
    }
    

    Code für 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. 
                }
            }
        }
    }
    

    Code für 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;
            }
        }
    }
    

    Code für 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;
            }
        }
    }
    

    Code für 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. 
                }
            }
        }
    }
    
  3. Kompilieren und erstellen Sie die Lösung. Sie verfügen nun über eine Assembly-Datei (.dll), die Sie zur Registrierung in Ihrer Dataverse-Umgebung verwenden können. Sie finden diese Datei im Lösungsordner/bin/Debug Verzeichnis.

    Assembly dll.

  4. Registrieren Sie die Assembly mit dem Plugin Registration Tool. Sie können das neueste Plugin Registration Tool-Paket von NuGet erhalten.

  5. Öffnen Sie das Plugin Registration Tool. Sie müssen über Systemadministrationsrechte verfügen, um die Assembly zu registrieren. Wählen Sie NEUE VERBINDUNG ERSTELLEN, um eine Verbindung zu Ihrer Dataverse-Umgebung herzustellen. Wählen Sie das Dropdown-Menü Registrieren und wählen Sie dann Neue Assembly registrieren.

    Neuen Schritt registrieren.

  6. Wählen Sie die Assembly-Datei und registrieren Sie die Plug-ins. Vergewissern Sie sich, dass Sie alle Plug-ins ausgewählt haben (Create-, Update-, Delete-, Retrieve- und RetrieveMultiple-Plug-ins).

    Neue Assembly registrieren.

Schritt 2: Erstellen des Datenproviders und Hinzufügen von Plug-ins zum Provider

  1. Wählen Sie das Dropdown-Menü Registrieren und dann Neuen Datenprovider registrieren.

  2. Geben Sie im Dialog Neuen Datenanbieter registrieren die folgenden Details ein:

    1. Geben Sie Datenprovider-Name ein.

    2. Wählen Sie in der Option Lösungen eine vorhandene Lösung aus oder erstellen Sie eine neue Lösung in der Dropdown-Liste. Wenn Sie eine neue Lösung erstellen wollen, wählen Sie in der Dropdown-Liste die Option NewSolution. Geben Sie im Dialog Neue Lösung erstellen die erforderlichen Details ein und wählen Sie Speichern.

    3. Wählen Sie in der Option Datentabellenquelle (Entität) die Option Neue Datenquelle erstellen. Geben Sie die Details ein. Stellen Sie sicher, dass die Datenquelle Teil der Lösung ist, die Sie erstellt oder ausgewählt haben.

      Hinweis

      Die Datenquellentabelle in Dataverse enthält die Konfigurationsdaten für einen Datensatz der Datenquelle, der an die Provider-Plug-ins übergeben werden soll.

    4. Ordnen Sie jedes der registrierten Plug-Ins den jeweiligen Operationen zu.

    5. Registrieren Sie den neuen Datenanbieter.

      Datenanbieter registrieren.

  3. Im Plugin Registration Tool sehen Sie den neuen Datensatz der Datenquelle und den zugehörigen Datenanbieter. Wenn Sie die Datenquelle auswählen, werden die Details angezeigt, die die Plug-ins und ihre registrierte GUID enthalten.

    Registrierter Datenanbieter.

Schritt 3: Erstellen einer virtuellen Tabelle in Dataverse-Umgebung

  1. Erstellen Sie eine neue Datenquelle für eine virtuelle Tabelle, indem Sie zu Einstellungen > Verwaltung > Virtuelle Tabelle (Entitäten)-Datenquellen navigieren.

  2. Wählen Sie Neu und wählen Sie dann den Datenanbieter, den Sie im vorherigen Schritt erstellt haben, aus der Dropdown-Liste.

  3. Geben Sie einen Namen für die Datenquelle ein und wählen Sie Speichern und schließen.

  4. Jetzt können Sie die virtuelle Tabelle erstellen, die die externe Datenquelle darstellt. Gehen Sie dazu auf Einstellungen > Anpassen des Systems.

  5. Wählen Sie im linken Navigationsbereich des Lösungsexplorers Tabellen (Entitäten) und dann Neu.

  6. Geben Sie die folgenden Details ein:

    Spalte Beschreibung
    Datenquelle Wählen Sie die Datenquelle, die Sie im vorherigen Schritt erstellt haben.
    Anzeigename Virtueller Tabellenname.
    Pluralname Der Wert wird automatisch auf der Basis des Anzeigenamens ausgefüllt.
    Name des Dataflows Dieser wird ebenfalls automatisch erstellt, basierend auf dem Wert, den Sie für den Anzeigenamen eingeben.
    Externer Name Der Name der Quelltabelle.
    Externe Sammlungen Name Sie können denselben Wert aus der Spalte Pluralname verwenden.
  7. Wählen Sie Speichern und schließen aus.

    Neuen Datensatz erstellen.

  8. Wählen Sie im linken Navigationsbereich die von Ihnen erstellte virtuelle Tabelle aus und erweitern Sie sie.

  9. Wählen Sie Felder, um neue Spalten zu aktualisieren und zu erstellen, die die externe Quelle darstellen.

  10. Wählen Sie die Spalte Primärschlüssel für die virtuelle Tabelle und wählen Sie Bearbeiten.

  11. Aktualisieren Sie die Spalte Externer Name, damit sie mit dem Spaltennamen in Ihrer externen Datenquelle übereinstimmt. In diesem Beispiel lautet der Name der externen Spalte TicketID.

    Neue Tabelle erstellen.

  12. Klicken Sie auf Speichern und schließen.

  13. Markieren Sie das Feld Name für die virtuelle Tabelle und wählen Sie Bearbeiten.

  14. Aktualisieren Sie das Feld Externer Name, damit es mit dem Feldnamen in Ihrer externen Datenquelle übereinstimmt. In diesem Beispiel lautet der Name der externen Spalte Name.

    Neues Namensfeld erstellen.

  15. Klicken Sie auf Speichern und schließen.

  16. Wählen Sie Neu, um eine neue Spalte in der virtuellen Tabelle zu erstellen. Diese Spalte wird die Schweregrad-Spalte in der externen Datenquelle darstellen.

  17. Geben Sie die folgenden Informationen für die neuen Spalten ein:

    Spaltenname Wert
    Anzeigename Schweregrad
    Name des Dataflows new_severity
    Externer Name Schweregrad
    Feldanforderung Eingabe erforderlich
    Datentyp Ganze Zahl

    Neues Schweregrad-Feld erstellen.

  18. Klicken Sie auf Speichern und schließen.

Schritt 4: Datensätze mit einer virtuellen Tabelle erstellen, aktualisieren, anzeigen und löschen

Erstellen Sie eine modellbasierte App und fügen Sie die virtuelle Tabelle der Site-Map zu. Wählen Sie dann das Hauptformular der virtuellen Tabelle und die Ansicht „Erweitertes Feld“. Veröffentlichen Sie die App. Weitere Informationen: Erstellen Sie Ihre erste modellbasierte App von Grund auf

Modellbasierte App erstellen.

Benutzer der Anwendung können mit der virtuellen Tabelle Lese-, Erstellungs-, Aktualisierungs- und Löschvorgänge durchführen, wie mit jeder anderen Tabelle in Microsoft Dataverse.

Siehe auch

Einstieg in virtuelle Tabellen
API-Überlegungen für virtuelle Tabellen
Anbieter von benutzerdefinierter virtueller Tabellendaten
Beispielhafte Vorgehensweise für virtuelle Tabellen mit OData v4 Data Provider