您现在访问的是微软AZURE全球版技术文档网站,若需要访问由世纪互联运营的MICROSOFT AZURE中国区技术文档网站,请访问 https://docs.azure.cn.

使用 Azure 数字孪生 API 编写代码Coding with the Azure Digital Twins APIs

开发人员使用 Azure 数字孪生编写客户端应用程序,以与其 Azure 数字孪生服务实例交互,这是很常见的情况。It is common for developers working with Azure Digital Twins to write a client application for interacting with their instance of the Azure Digital Twins service. 这篇面向开发人员的教程介绍如何使用适用于 .NET 的 Azure IoT 数字孪生客户端库 (C#) 对 Azure 数字孪生服务进行编程。This developer-focused tutorial provides an introduction to programming against the Azure Digital Twins service, using the Azure IoT Digital Twin client library for .NET (C#). 本教程会逐步引导你从头开始编写 C# 控制台客户端应用。It walks you through writing a C# console client app step by step, starting from scratch.

先决条件Prerequisites

本教程使用命令行执行设置和项目工作。This tutorial uses the command line for setup and project work. 因此,你可以使用任何代码编辑器来逐步完成练习。Therefore, you can use any code editor to walk through the exercises.

准备工作:What you need to begin:

  • 任何代码编辑器Any code editor
  • 开发电脑上安装有 .NET Core 3.1。.NET Core 3.1 on your development machine. 你可以从下载 .NET Core 3.1 下载适用于多个平台的此版 .NET Core SDK。You can download this version of the .NET Core SDK for multiple platforms from Download .NET Core 3.1.

准备 Azure 数字孪生实例Prepare an Azure Digital Twins instance

要完成本教程,需要一个要对其进行编程的 Azure 数字孪生实例To complete this tutorial, you'll need an Azure Digital Twins instance to program against. 如果已有通过以前的工作设置的 Azure 数字孪生实例,则可以使用该实例,然后跳到下一部分。If you already have an Azure Digital Twins instance set up from previous work, you can use that instance, and skip to the next section.

否则,使用操作方法:设置实例和身份验证中的说明设置实例和身份验证。Otherwise, set up an instance and authentication using the instructions in How-to: Set up an instance and authentication. 说明中还包含用于验证是否已成功完成每个步骤并准备好继续使用新实例的步骤。The instructions also contain steps to verify that you have completed each step successfully and are ready to move on to using your new instance.

设置项目Set up project

准备好使用 Azure 数字孪生实例后,请开始设置客户端应用项目。Once you are ready to go with your Azure Digital Twins instance, start setting up the client app project.

在计算机上打开命令提示符或其他控制台窗口,创建用于存储本教程工作的空项目目录。Open a command prompt or other console window on your machine, and create an empty project directory where you would like to store your work during this tutorial. 将目录命名为任何你喜欢的名称(例如,DigitalTwinsCodeTutorial)。Name the directory whatever you would like (for example, DigitalTwinsCodeTutorial).

导航到新目录。Navigate into the new directory.

进入项目目录后,创建一个空的 .NET 控制台应用项目。Once in the project directory, create an empty .NET console app project. 在命令窗口中运行以下命令,为控制台创建基础 C# 项目:In the command window, run the following command to create a minimal C# project for the console:

dotnet new console

这会在你的目录中创建多个文件,其中包括一个名为 Program.cs 的文件,你将在其中编写大部分代码。This will create several files inside your directory, including one called Program.cs where you will write most of your code.

接下来,添加两个使用 Azure 数字孪生所必须的依赖项:Next, add two necessary dependencies for working with Azure Digital Twins:

dotnet add package Azure.DigitalTwins.Core --version 1.0.0-preview.3
dotnet add package Azure.identity

第一个依赖项是适用于 .NET 的 Azure IoT 数字孪生客户端库The first dependency is the Azure IoT Digital Twin client library for .NET. 第二个依赖项会提供可帮助进行 Azure 身份验证的工具。The second dependency provides tools to help with authentication against Azure.

让命令窗口保持打开状态,因为整个教程都要继续使用该窗口。Keep the command window open, as you'll continue to use it throughout the tutorial.

开始使用项目代码Get started with project code

在本部分中,你将开始编写新应用项目的代码以使用 Azure 数字孪生。In this section, you will begin writing the code for your new app project to work with Azure Digital Twins. 涵盖的操作包括:The actions covered include:

  • 对服务进行身份验证Authenticating against the service
  • 上传模型Uploading a model
  • 捕获错误Catching errors
  • 创建数字孪生Creating digital twins
  • 创建关系Creating relationships
  • 查询数字孪生Querying digital twins

在本教程末尾,另有一节显示了完整的代码。There is also a section showing the complete code at the end of the tutorial. 你可以将其用作参考,随时检查自己的程序。You can use this as a reference to check your program as you go.

开始前,请在任何代码编辑器中打开 Program.cs 文件。To begin, open the file Program.cs in any code editor. 你将看到如下所示的基础代码模板:You will see a minimal code template that looks like this:

using System;

namespace DigitalTwinsCodeTutorial
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
    }
}

首先,在代码的顶部添加一些 using 行,以拉取必需的依赖项。First, add some using lines at the top of the code to pull in necessary dependencies.

using Azure.DigitalTwins.Core;
using Azure.Identity;

接下来,需要向此文件添加代码以扩充某些功能。Next, you'll add code to this file to fill out some functionality.

对服务进行身份验证Authenticate against the service

应用必须执行的第一项操作是对 Azure 数字孪生服务进行身份验证。The first thing your app will need to do is authenticate against the Azure Digital Twins service. 接着,你可以创建服务客户端类来访问 SDK 函数。Then, you can create a service client class to access the SDK functions.

为进行身份验证,需要以下三条信息:In order to authenticate, you need three pieces of information:

  • 订阅的目录(租户)IDThe Directory (tenant) ID for your subscription
  • 在之前设置 Azure 数字孪生实例时创建的应用程序(客户端)IDThe Application (client) ID created when you set up the Azure Digital Twins instance earlier
  • Azure 数字孪生实例的 hostNameThe hostName of your Azure Digital Twins instance

提示

如果不知道自己的目录(租户)ID,可以在 Azure Cloud Shell 中运行以下命令来获取该 ID:If you don't know your Directory (tenant) ID, you can get it by running this command in Azure Cloud Shell:

az account show --query tenantId

在 Program.cs 中,将以下代码粘贴到In Program.cs, paste the following code below the "Hello, World!" Main 方法中的“Hello, World!”输出行下方。printout line in the Main method. adtInstanceUrl 的值设置为 Azure 数字孪生实例的主机名,将 clientId 设置为应用程序 ID,并将 tenantId 设置为目录 ID 。Set the value of adtInstanceUrl to your Azure Digital Twins instance hostName, clientId to your Application ID, and tenantId to your Directory ID.

string clientId = "<your-application-ID>";
string tenantId = "<your-directory-ID>";
string adtInstanceUrl = "https://<your-Azure-Digital-Twins-instance-hostName>";
var credentials = new InteractiveBrowserCredential(tenantId, clientId);
DigitalTwinsClient client = new DigitalTwinsClient(new Uri(adtInstanceUrl), credentials);
Console.WriteLine($"Service client created – ready to go");

保存文件。Save the file.

请注意,此示例使用交互式浏览器凭据:Note that this example uses an interactive browser credential:

var credentials = new InteractiveBrowserCredential(tenantId, clientId);

这种类型的凭据将导致浏览器窗口打开,并要求你提供 Azure 凭据。This type of credential will cause a browser window to open, asking you to provide your Azure credentials.

备注

要了解其他类型的凭据,请参阅 Microsoft 标识平台身份验证库文档。For information on other types of credentials, see the documentation for the Microsoft identity platform authentication libraries.

在命令窗口中,使用以下命令运行代码:In your command window, run the code with this command:

dotnet run

首次运行时,这会还原依赖项,然后执行程序。This will restore the dependencies on first run, and then execute the program.

  • 如果未发生错误,程序将输出“Service client created - ready to go”(服务客户端已创建 - 准备就绪)。If no error occurs, the program will print Service client created - ready to go.
  • 由于此项目中没有任何错误处理机制,因此如果出现问题,你将看到代码引发的异常。Since there is not yet any error handling in this project, if anything goes wrong, you will see an exception thrown by the code.

上传模型Upload a model

Azure 数字孪生没有内部域词汇。Azure Digital Twins has no intrinsic domain vocabulary. 环境中可在 Azure 数字孪生中表示的元素类型由你使用模型定义。The types of elements in your environment that you can represent in Azure Digital Twins are defined by you, using models. 模型类似于面向对象的编程语言中的类;它们为数字孪生提供了日后可遵循并实例化的用户定义的模板。Models are similar to classes in object-oriented programming languages; they provide user-defined templates for digital twins to follow and instantiate later. 它们以类似于 JSON 的语言编写,这种语言称为数字孪生定义语言 (DTDL)。They are written in a JSON-like language called Digital Twins Definition Language (DTDL).

创建 Azure 数字孪生解决方案的第一步是在 DTDL 文件中至少定义一个模型。The first step in creating an Azure Digital Twins solution is defining at least one model in a DTDL file.

在创建项目的目录中,创建名为 SampleModel.json 的新 .json 文件 。In the directory where you created your project, create a new .json file called SampleModel.json. 粘贴以下文件主体:Paste in the following file body:

{
  "@id": "dtmi:com:contoso:SampleModel;1",
  "@type": "Interface",
  "displayName": "SampleModel",
  "contents": [
    {
      "@type": "Relationship",
      "name": "contains"
    },
    {
      "@type": "Property",
      "name": "data",
      "schema": "string"
    }
  ],
  "@context": "dtmi:dtdl:context;2"
}

提示

如果在本教程中使用 Visual Studio,建议你选择新创建的 JSON 文件,并将属性检查器中的“复制到输出目录”属性设置为“有更新时才复制”或“始终复制” 。If you're using Visual Studio for this tutorial, you may want to select the newly-created JSON file and set the Copy to Output Directory property in the Property inspector to Copy if Newer or Copy Always. 当你在本教程的其余部分使用 F5 执行程序时,这可让 Visual Studio 找到具有默认路径的 JSON 文件。This will enable Visual Studio to find the JSON file with the default path when you run the program with F5 during the rest of the tutorial.

提示

有一种与语言无关的 DTDL 验证程序示例,可用来检查模型文件,以确保 DTDL 有效。There is a language-agnostic DTDL Validator sample that you can use to check model documents to make sure the DTDL is valid. 它是在 DTDL 分析程序库的基础上构建的,详情请参阅操作方法:分析和验证模型It is built on the DTDL parser library, which you can read more about in How-to: Parse and validate models.

接下来,向 Program.cs 添加更多代码,将刚才创建的模型上传到 Azure 数字孪生实例。Next, add some more code to Program.cs to upload the model you've just created into your Azure Digital Twins instance.

首先,在文件顶部添加几个 using 语句:First, add a few using statements to the top of the file:

using System.Threading.Tasks;
using System.IO;
using System.Collections.Generic;
using Azure;

接下来,将 Main 方法签名更改为允许异步执行,准备使用 C# 服务 SDK 中的异步方法。Next, prepare to use the asynchronous methods in the C# service SDK, by changing the Main method signature to allow for async execution.

static async Task Main(string[] args)

备注

因为 SDK 也提供所有调用的同步版本,所以不一定非使用 async 不可。Using async is not strictly required, as the SDK also provides synchronous versions of all calls. 本教程的练习使用 asyncThis tutorial practices using async.

接下来是与 Azure 数字孪生服务交互的第一段代码。Next comes the first bit of code that interacts with the Azure Digital Twins service. 此代码将加载你从磁盘创建的 DTDL 文件,然后将其上传到 Azure 数字孪生服务实例。This code loads the DTDL file you created from your disk, and then uploads it to your Azure Digital Twins service instance.

将以下代码粘贴到前面添加的授权代码下。Paste in the following code under the authorization code you added earlier.

Console.WriteLine();
Console.WriteLine($"Upload a model");
var typeList = new List<string>();
string dtdl = File.ReadAllText("SampleModel.json");
typeList.Add(dtdl);
// Upload the model to the service
await client.CreateModelsAsync(typeList);

在命令窗口中,使用以下命令运行程序:In your command window, run the program with this command:

dotnet run

输出中将打印“上传模型”短语,但尚无输出指出模型是否已成功上传。"Upload a model" will be printed in the output, but there is no output yet to indicate whether or not models were uploaded successfully.

若要添加一个指示模型是否确实已成功上传的 print 语句,请在上一段代码后面添加以下代码:To add a print statement indicating whether models are actually uploaded successfully, add the following code right after the previous section:

// Read a list of models back from the service
AsyncPageable<ModelData> modelDataList = client.GetModelsAsync();
await foreach (ModelData md in modelDataList)
{
    Console.WriteLine($"Type name: {md.DisplayName}: {md.Id}");
}

再次运行程序以测试这段新代码之前,请记得,在上次运行该程序时,已上传了模型。Before you run the program again to test this new code, recall that the last time you ran the program, you uploaded your model already. Azure 数字孪生不允许将相同的模型上传两次,因此,在重新运行此程序时,应该会看到异常。Azure Digital Twins will not let you upload the same model twice, so expect to see an exception when you re-run the program.

现在,在命令窗口中,再次使用以下命令运行程序:Now, run the program again with this command in your command window:

dotnet run

程序应该会引发异常。The program should throw an exception. 当你尝试上传已上传过的模型时,服务会通过 REST API 返回“请求错误”错误。When you attempt to upload a model that has been uploaded already, the service returns a "bad request" error via the REST API. 因此,Azure 数字孪生客户端 SDK 会针对不成功的每个服务返回代码引发异常。As a result, the Azure Digital Twins client SDK will in turn throw an exception, for every service return code other than success.

下一节将讨论与此类似的异常以及如何在代码中予以处理。The next section talks about exceptions like this and how to handle them in your code.

捕获错误Catch errors

为了防止程序崩溃,可以在模型上传代码周围添加异常代码。To keep the program from crashing, you can add exception code around the model upload code. 在 try/catch 处理程序中包装现有的客户端调用 client.CreateModelsAsync,如下所示:Wrap the existing client call client.CreateModelsAsync in a try/catch handler, like this:

try {
    await client.CreateModelsAsync(typeList);
} catch (RequestFailedException rex) {
    Console.WriteLine($"Load model: {rex.Status}:{rex.Message}");
}

如果在命令窗口中使用 dotnet run 运行程序,则会看到返回的错误代码。If you run the program with dotnet run in your command window now, you will see that you get an error code back. 输出结果如下所示:The output looks something like this:

Hello World!
Service client created - ready to go

Upload a model
Load model: 409:Service request failed.
Status: 409 (Conflict)

Content:
{"error":{"code":"DocumentAlreadyExists","message":"A document with same identifier already exists.","details":[]}}

Headers:
api-supported-versions: REDACTED
Date: Tue, 05 May 2020 01:57:51 GMT
Content-Length: 115
Content-Type: application/json; charset=utf-8

Type name: : dtmi:com:contoso:SampleModel;1

从此时起,本教程会将所有对服务方法的调用包装在 try/catch 处理程序中。From this point forward, the tutorial will wrap all calls to service methods in try/catch handlers.

创建数字孪生Create digital twins

将模型上传到 Azure 数字孪生后,可以使用此模型定义创建数字孪生。Now that you have uploaded a model to Azure Digital Twins, you can use this model definition to create digital twins. 数字孪生是模型的实例,表示业务环境中的实体,例如农场中的传感器、大楼中的房间或汽车上的灯。Digital twins are instances of a model, and represent the entities within your business environment—things like sensors on a farm, rooms in a building, or lights in a car. 本部分将在你之前上传的模型的基础上创建几个数字孪生。This section creates a few digital twins based on the model you uploaded earlier.

在顶部添加新的 using 语句,因为在 System.Text.Json 中需要内置的 .NET Json 序列化程序:Add a new using statement at the top, as you will need the built-in .NET Json serializer in System.Text.Json:

using System.Text.Json;
using Azure.DigitalTwins.Core.Serialization;

然后,将以下代码添加到 Main 方法的末尾,以根据此模型创建和初始化三个数字孪生。Then, add the following code to the end of the Main method to create and initialize three digital twins based on this model.

// Initialize twin data
BasicDigitalTwin twinData = new BasicDigitalTwin();
twinData.Metadata.ModelId = "dtmi:com:contoso:SampleModel;1";
twinData.CustomProperties.Add("data", $"Hello World!");

string prefix="sampleTwin-";
for(int i=0; i<3; i++) {
    try {
        twinData.Id = $"{prefix}{i}";
        await client.CreateDigitalTwinAsync($"{prefix}{i}", JsonSerializer.Serialize(twinData));
        Console.WriteLine($"Created twin: {prefix}{i}");
    } catch(RequestFailedException rex) {
        Console.WriteLine($"Create twin error: {rex.Status}:{rex.Message}");  
    }
}

在命令窗口中,使用 dotnet run 运行程序。In your command window, run the program with dotnet run. 然后,再次运行该程序。Then, repeat to run the program again.

请注意,第二次创建孪生时,即使孪生在第一次运行后已经存在,也不会引发任何错误。Notice that no error is thrown when the twins are created the second time, even though the twins already exist after the first run. 与创建模型不同,在 REST 级别上,创建孪生是 PUT 调用加上 upsert 语义 。Unlike model creation, twin creation is, on the REST level, a PUT call with upsert semantics. 这意味着,如果已存在一个孪生,尝试再次创建将会替换该孪生。This means that if a twin already exists, trying to create it again will just replace it. 不需要有任何错误。No error required.

创建关系Create relationships

接下来,你可以在已创建的孪生之间创建关系,将它们连接到孪生图 。Next, you can create relationships between the twins you've created, to connect them into a twin graph. 孪生图用于表示整个环境。Twin graphs are used to represent your entire environment.

为了能够创建关系,请在 SDK 中为关系基类型添加 using 语句(如果已添加,请跳过此步骤)。To be able to create relationships, add a using statement for the relationship base type in the SDK:skip this if already added.

using Azure.DigitalTwins.Core.Serialization;

接下来,将新的静态方法添加到 Main 方法下的 Program 类:Next, add a new static method to the Program class, underneath the Main method:

public async static Task CreateRelationship(DigitalTwinsClient client, string srcId, string targetId)
{
    var relationship = new BasicRelationship
    {
        TargetId = targetId,
        Name = "contains"
    };

    try
    {
        string relId = $"{srcId}-contains->{targetId}";
        await client.CreateRelationshipAsync(srcId, relId, JsonSerializer.Serialize(relationship));
        Console.WriteLine("Created relationship successfully");
    }
    catch (RequestFailedException rex) {
        Console.WriteLine($"Create relationship error: {rex.Status}:{rex.Message}");
    }
}

然后,将以下代码添加到 Main 方法的末尾,以调用 CreateRelationship 代码:Then, add the following code to the end of the Main method to call the CreateRelationship code:

// Connect the twins with relationships
await CreateRelationship(client, "sampleTwin-0", "sampleTwin-1");
await CreateRelationship(client, "sampleTwin-0", "sampleTwin-2");

在命令窗口中,使用 dotnet run 运行程序。In your command window, run the program with dotnet run.

请注意,如果已存在 ID 相同的关系,Azure 数字孪生将不会让你创建关系;因此,如果多次运行程序,你将会看到有关创建关系的异常。Note that Azure Digital Twins will not let you create a relationship if one with the same ID already exists—so if you run the program multiple times, you will see exceptions on relationship creation. 此代码会捕获异常并将其忽略。This code catches the exceptions and ignores them.

列出关系List relationships

你将添加的下一段代码可让你查看已创建的关系列表。The next code you'll add allows you to see the list of relationships you've created.

将以下新方法添加到 Program 类:Add the following new method to the Program class:

public async static Task ListRelationships(DigitalTwinsClient client, string srcId)
{
    try {
        AsyncPageable<string> results = client.GetRelationshipsAsync(srcId);
        Console.WriteLine($"Twin {srcId} is connected to:");
        await foreach (string rel in results)
        {
            var brel = JsonSerializer.Deserialize<BasicRelationship>(rel);
            Console.WriteLine($" -{brel.Name}->{brel.TargetId}");
        }
    } catch (RequestFailedException rex) {
        Console.WriteLine($"Relationship retrieval error: {rex.Status}:{rex.Message}");   
    }
}

然后,将以下代码添加到 Main 方法的末尾,以调用 ListRelationships 代码:Then, add the following code to the end of the Main method to call the ListRelationships code:

//List the relationships
await ListRelationships(client, "sampleTwin-0");

在命令窗口中,使用 dotnet run 运行程序。In your command window, run the program with dotnet run. 你应该会看到已创建的所有关系列表。You should see a list of all the relationships you have created.

查询数字孪生Query digital twins

Azure 数字孪生的主要功能是能够轻松有效地查询孪生图,以解答有关环境的问题。A main feature of Azure Digital Twins is the ability to query your twin graph easily and efficiently to answer questions about your environment.

要在本教程中添加的最后一段代码会对对 Azure 数字孪生实例运行查询。The last section of code to add in this tutorial runs a query against the Azure Digital Twins instance. 本示例中使用的查询会返回此实例中的所有数字孪生。The query used in this example returns all the digital twins in the instance.

Main 方法的末尾添加以下代码:Add the following code to the end of the Main method:

// Run a query    
AsyncPageable<string> result = client.QueryAsync("Select * From DigitalTwins");
await foreach (string twin in result)
{
    object jsonObj = JsonSerializer.Deserialize<object>(twin);
    string prettyTwin = JsonSerializer.Serialize(jsonObj, new JsonSerializerOptions { WriteIndented = true });
    Console.WriteLine(prettyTwin);
    Console.WriteLine("---------------");
}

在命令窗口中,使用 dotnet run 运行程序。In your command window, run the program with dotnet run. 你应该会在输出中看到此实例中的所有数字孪生。You should see all the digital twins in this instance in the output.

完整代码示例Complete code example

到本教程的此阶段,你已有一个完整的客户端应用,能够对 Azure 数字孪生执行基本操作。At this point in the tutorial, you have a complete client app, capable of performing basic actions against Azure Digital Twins. 下面列出了 Program.cs 中的程序的完整代码供你参考:For reference, the full code of the program in Program.cs is listed below:

using System;
using Azure.DigitalTwins.Core;
using Azure.Identity;
using System.Threading.Tasks;
using System.IO;
using System.Collections.Generic;
using Azure;
using Azure.DigitalTwins.Core.Models;
using Azure.DigitalTwins.Core.Serialization;
using System.Text.Json;

namespace minimal
{
    class Program
    {
        static async Task Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            
            string clientId = "<your-application-ID>";
            string tenantId = "<your-directory-ID>";
            string adtInstanceUrl = "https://<your-Azure-Digital-Twins-instance-hostName>";
            var credentials = new InteractiveBrowserCredential(tenantId, clientId);
            DigitalTwinsClient client = new DigitalTwinsClient(new Uri(adtInstanceUrl), credentials);
            Console.WriteLine($"Service client created – ready to go");

            Console.WriteLine();
            Console.WriteLine($"Upload a model");
            var typeList = new List<string>();
            string dtdl = File.ReadAllText("SampleModel.json");
            typeList.Add(dtdl);

            // Upload the model to the service
            try {
                await client.CreateModelsAsync(typeList);
            } catch (RequestFailedException rex) {
                Console.WriteLine($"Load model: {rex.Status}:{rex.Message}");
            }
            // Read a list of models back from the service
            AsyncPageable<ModelData> modelDataList = client.GetModelsAsync();
            await foreach (ModelData md in modelDataList)
            {
                Console.WriteLine($"Type name: {md.DisplayName}: {md.Id}");
            }

            // Initialize twin data
            BasicDigitalTwin twinData = new BasicDigitalTwin();
            twinData.Metadata.ModelId = "dtmi:com:contoso:SampleModel;1";
            twinData.CustomProperties.Add("data", $"Hello World!");
    
            string prefix="sampleTwin-";
            for(int i=0; i<3; i++) {
                try {
                    twinData.Id = $"{prefix}{i}";
                    await client.CreateDigitalTwinAsync($"{prefix}{i}", JsonSerializer.Serialize(twinData));
                    Console.WriteLine($"Created twin: {prefix}{i}");
                } catch(RequestFailedException rex) {
                    Console.WriteLine($"Create twin error: {rex.Status}:{rex.Message}");  
                }
            }

            // Connect the twins with relationships
            await CreateRelationship(client, "sampleTwin-0", "sampleTwin-1");
            await CreateRelationship(client, "sampleTwin-0", "sampleTwin-2");

            //List the relationships
            await ListRelationships(client, "sampleTwin-0");

            // Run a query    
            AsyncPageable<string> result = client.QueryAsync("Select * From DigitalTwins");
            await foreach (string twin in result)
            {
                object jsonObj = JsonSerializer.Deserialize<object>(twin);
                string prettyTwin = JsonSerializer.Serialize(jsonObj, new JsonSerializerOptions { WriteIndented = true });
                Console.WriteLine(prettyTwin);
                Console.WriteLine("---------------");
            }
        }

        public async static Task CreateRelationship(DigitalTwinsClient client, string srcId, string targetId)
        {
            var relationship = new BasicRelationship
            {
                TargetId = targetId,
                Name = "contains"
            };
        
            try
            {
                string relId = $"{srcId}-contains->{targetId}";
                await client.CreateRelationshipAsync(srcId, relId, JsonSerializer.Serialize(relationship));
                Console.WriteLine("Created relationship successfully");
            }
            catch (RequestFailedException rex) {
                Console.WriteLine($"Create relationship error: {rex.Status}:{rex.Message}");
            }
        }
        
        public async static Task ListRelationships(DigitalTwinsClient client, string srcId)
        {
            try {
                AsyncPageable<string> results = client.GetRelationshipsAsync(srcId);
                Console.WriteLine($"Twin {srcId} is connected to:");
                await foreach (string rel in results)
                {
                    var brel = JsonSerializer.Deserialize<BasicRelationship>(rel);
                    Console.WriteLine($" -{brel.Name}->{brel.TargetId}");
                }
            } catch (RequestFailedException rex) {
                Console.WriteLine($"Relationship retrieval error: {rex.Status}:{rex.Message}");   
            }
        }

    }
}

清理资源Clean up resources

本教程中使用的实例可重复用于下一教程教程:使用示例客户端应用了解基础知识The instance used in this tutorial can be reused in the next tutorial, Tutorial: Explore the basics with a sample client app. 如果打算继续学习下一个教程,可以保留在此处设置的 Azure 数字孪生实例。If you plan to continue to the next tutorial, you can keep the Azure Digital Twins instance you set up here.

如果不再需要本教程中创建的资源,请按照以下步骤将其删除。If you no longer need the resources created in this tutorial, follow these steps to delete them.

利用 Azure Cloud Shell,你可以使用 az group delete 命令删除资源组中的所有 Azure 资源。Using the Azure Cloud Shell, you can delete all Azure resources in a resource group with the az group delete command. 这将删除资源组和 Azure 数字孪生实例。This removes the resource group and the Azure Digital Twins instance.

重要

删除资源组的操作不可逆。Deleting a resource group is irreversible. 资源组以及包含在其中的所有资源将被永久删除。The resource group and all the resources contained in it are permanently deleted. 请确保不会意外删除错误的资源组或资源。Make sure that you do not accidentally delete the wrong resource group or resources.

打开 Azure Cloud Shell 并运行以下命令,以删除资源组及其包含的所有内容。Open an Azure Cloud Shell and run the following command to delete the resource group and everything it contains.

az group delete --name <your-resource-group>

接下来,使用以下命令删除为客户端应用创建的 Azure Active Directory 应用注册:Next, delete the Azure Active Directory app registration you created for your client app with this command:

az ad app delete --id <your-application-ID>

最后,删除在本地计算机上创建的项目文件夹。Finally, delete the project folder you created on your local machine.

后续步骤Next steps

在本教程中,你从头开始创建了 .NET 控制台客户端应用程序。In this tutorial, you created a .NET console client application from scratch. 你为此客户端应用编写了代码,在 Azure 数字孪生实例上执行基本操作。You wrote code for this client app to perform the basic actions on an Azure Digital Twins instance.

请继续学习下一个教程,了解可使用这类示例客户端应用执行的操作:Continue to the next tutorial to explore the things you can do with such a sample client app:

你也可以在操作说明文章中了解更多管理操作,以增加在本教程中编写的代码,或开始查看概念文档,详细了解教程中使用的元素。You can also add to the code you wrote in this tutorial by learning more management operations in the how-to articles, or start looking at the concept documentation to learn more about elements you worked with in the tutorial.