자습서: Azure Digital Twins SDK를 사용하여 코딩

Azure Digital Twins를 사용하는 개발자는 일반적으로 Azure Digital Twins 서비스 인스턴스와 상호 작용하기 위한 클라이언트 애플리케이션을 작성합니다. 이 개발자 중심 자습서에서는 .NET(C#)용 Azure Digital Twins SDK를 사용하여 Azure Digital Twins 서비스에 대한 프로그래밍을 소개합니다. C# 콘솔 클라이언트 앱을 작성하는 과정을 처음부터 단계별로 안내합니다.

  • 프로젝트 설정
  • 프로젝트 코드 시작
  • 전체 코드 샘플
  • 리소스 정리
  • 다음 단계

필수 조건

이 Azure Digital Twins 자습서에서는 설정 및 프로젝트 작업에 명령줄을 사용합니다. 따라서 원하는 코드 편집기를 사용하여 연습 과정을 진행할 수 있습니다.

시작하기 위해 필요한 사항:

  • 코드 편집기
  • 개발 머신에 설치된 .NET Core 3.1. .NET Core 3.1 다운로드에서 여러 플랫폼을 위한 .NET Core SDK의 이 버전을 다운로드할 수 있습니다.

Azure Digital Twins 인스턴스 준비하기

이 문서에서 Azure Digital Twins로 작업하려면 Azure Digital Twins 인스턴스와 이를 사용하는 데 필요한 권한이 필요합니다. 이미 Azure Digital Twins 인스턴스를 설정한 경우 해당 인스턴스를 사용하고 다음 섹션으로 건너뛸 수 있습니다. 그렇지 않으면 인스턴스 및 인증 설정의 지침을 따릅니다. 지침에는 각 단계를 성공적으로 완료했는지 확인하는 데 도움이 되는 정보가 포함되어 있습니다.

인스턴스가 설정되면 인스턴스의 호스트 이름을 적어 둡니다. Azure Portal에서 호스트 이름을 찾을 수 있습니다.

로컬 Azure 자격 증명 설정

이 샘플은 로컬 컴퓨터에서 실행할 때 DefaultAzureCredential(Azure.Identity 라이브러리의 일부)을 사용하여 Azure Digital Twins 인스턴스에서 사용자를 인증합니다. 클라이언트 앱에서 Azure Digital Twins를 사용하여 인증하는 여러 방법에 대한 자세한 내용은 앱 인증 코드 작성을 참조하세요.

DefaultAzureCredential을 사용하면 샘플에서 로컬 Azure CLI 또는 Visual Studio 또는 Visual Studio Code의 Azure 로그인과 같은 로컬 환경에서 자격 증명을 검색합니다. 이러한 이유로 샘플에 대한 자격 증명을 설정하려면 이러한 메커니즘 중 하나를 통해 Azure에 로컬로 로그인해야 합니다.

Visual Studio 또는 Visual Studio Code를 사용하여 코드 샘플을 실행하는 경우 Azure Digital Twins 인스턴스에 액세스하는 데 사용하려는 것과 동일한 Azure 자격 증명을 사용하여 해당 편집기에 로그인했는지 확인합니다. 로컬 CLI 창을 사용하는 경우 az login 명령을 실행하여 Azure 계정에 로그인합니다. 그런 다음 코드 샘플을 실행하면 자동으로 인증을 받아야 합니다.

프로젝트 설정

Azure Digital Twins 인스턴스로 이동할 준비가 되면 클라이언트 앱 프로젝트 설정을 시작합니다.

컴퓨터에서 콘솔 창을 열고, 이 자습서를 진행하는 동안 작업을 저장할 빈 프로젝트 디렉터리를 만듭니다. 디렉터리 이름을 원하는 대로 지정합니다(예: DigitalTwinsCodeTutorial).

새 디렉터리로 이동합니다.

프로젝트 디렉터리에서 빈 .NET 콘솔 앱 프로젝트를 만듭니다. 명령 창에서 다음 명령을 실행하여 콘솔에 사용할 최소 C# 프로젝트를 만들 수 있습니다.

dotnet new console

이 명령은 대부분의 코드를 작성할 Program.cs라는 파일을 포함하여 디렉터리 내에 여러 파일을 만듭니다.

자습서 전체에서 명령 창을 계속 사용하므로 명령 창을 열어 두세요.

다음으로, Azure Digital Twins와 함께 작동하는 데 필요한 두 개의 종속성을 프로젝트에 추가합니다. 첫 번째는 .NET용 Azure Digital Twins SDK의 패키지이고, 두 번째는 Azure에 대한 인증을 지원하는 도구를 제공합니다.

dotnet add package Azure.DigitalTwins.Core
dotnet add package Azure.Identity

프로젝트 코드 시작

이 섹션에서는 Azure Digital Twins에서 작동하는 새로운 앱 프로젝트의 코드 작성을 시작합니다. 다음과 같은 작업을 살펴봅니다.

  • 서비스에 대한 인증
  • 모델 업로드
  • 오류 catch
  • 디지털 트윈 만들기
  • 관계 만들기
  • 디지털 트윈 쿼리

자습서의 끝 부분에 전체 코드를 보여주는 섹션도 있습니다. 이 섹션을 참조로 사용하여 진행하면서 프로그램을 확인할 수 있습니다.

시작하려면 코드 편집기에서 Program.cs 파일을 엽니다. 다음과 같은 최소 코드 템플릿이 표시됩니다.

Screenshot of a snippet of sample code in a code editor.

먼저 코드 맨 위에 using 줄을 몇 개 추가하여 필요한 종속성을 가져옵니다.

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

그런 다음에는 이 파일에 코드를 추가하여 기능을 작성합니다.

서비스에 대한 인증

이 앱이 수행할 첫 번째 작업은 Azure Digital Twins 서비스에 대해 인증하는 것입니다. 그런 다음, 서비스 클라이언트 클래스를 만들어 SDK 함수에 액세스할 수 있습니다.

인증하려면 Azure Digital Twins 인스턴스의 호스트 이름이 필요합니다.

Program.cs에서 Main 메서드의 “Hello, World!” 인쇄 줄 아래에 다음 코드를 붙여넣습니다. adtInstanceUrl 값을 Azure Digital Twins 인스턴스 호스트 이름으로 설정합니다.

string adtInstanceUrl = "https://<your-Azure-Digital-Twins-instance-hostName>"; 

var credential = new DefaultAzureCredential();
var client = new DigitalTwinsClient(new Uri(adtInstanceUrl), credential);
Console.WriteLine($"Service client created – ready to go");

파일을 저장합니다.

명령 창에서 다음 명령을 사용하여 코드를 실행합니다.

dotnet run

이 명령은 처음 실행될 때 종속성을 복원한 다음, 프로그램을 실행합니다.

  • 오류가 발생하지 않으면 “Service client created - ready to go”가 출력됩니다.
  • 이 프로젝트에는 아직 오류 처리가 없으므로 문제가 있으면 코드에 의해 throw된 예외가 표시됩니다.

참고 항목

현재 인증하는 동안 오류가 발생할 수 있는 DefaultAzureCredential 래퍼 클래스에 영향을 미치는 알려진 문제가 있습니다. 이 문제가 발생하면 다음 선택적 매개 변수를 사용하여 DefaultAzureCredential을 인스턴스화하여 해결할 수 있습니다. new DefaultAzureCredential(new DefaultAzureCredentialOptions { ExcludeSharedTokenCacheCredential = true });

이 문제에 대한 자세한 내용은 Azure Digital Twins 알려진 문제를 참조하세요.

모델 업로드

Azure Digital Twins에는 내장 도메인 어휘가 없습니다. Azure Digital Twins에서 나타낼 수 있는 환경의 요소 유형은 사용자가 모델을 사용하여 정의합니다. 모델은 개체 지향 프로그래밍 언어의 클래스와 유사하며, 나중에 디지털 트윈이 따르고 인스턴스화할 수 있도록 사용자 정의 템플릿을 제공합니다. 이 템플릿은 DTDL(Digital Twins Definition Language)이라는 JSON과 유사한 언어로 작성됩니다.

Azure Digital Twins 솔루션을 만드는 첫 번째 단계는 DTDL 파일에 하나 이상의 모델을 정의하는 것입니다.

프로젝트를 만든 디렉터리에서 SampleModel.json이라는 새 .json 파일을 만듭니다. 다음 파일 본문을 붙여넣습니다.

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

이 자습서의 진행을 위해 Visual Studio를 사용하는 경우, 새로 만든 JSON 파일을 선택하고 속성 검사기에서 출력 디렉터리로 복사 속성을 변경된 내용만 복사 또는 항상 복사로 설정합니다. 이렇게 하면 자습서의 나머지 부분에서 F5를 사용하여 프로그램을 실행할 때 Visual Studio에서 기본 경로를 사용하여 JSON 파일을 찾을 수 있습니다.

모델 문서를 확인하여 DTDLParser 라이브러리를 사용하여 DTDL이 유효한지 확인할 수 있습니다. 이 라이브러리를 사용하는 방법에 대한 자세한 내용은 모델 구문 분석 및 유효성 검사를 참조하세요.

다음으로 Program.cs에 코드를 추가하여 만든 모델을 Azure Digital Twins 인스턴스에 업로드합니다.

먼저, 파일 맨 위에 몇 개의 using문을 추가합니다.

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

다음으로 비동기 실행을 허용하도록 Main 메서드 시그니처를 변경하여 C# 서비스 SDK에서 비동기 메서드를 사용할 준비를 합니다.

static async Task Main(string[] args)
{

참고 항목

SDK도 모든 호출의 동기 버전을 제공하므로 async를 반드시 사용해야 하는 것은 아닙니다. 이 자습서에서는 async를 사용합니다.

다음은 Azure Digital Twins 서비스와 상호 작용하는 코드의 첫 번째 비트입니다. 이 코드는 디스크에서 만든 DTDL 파일을 로드한 다음, 이 파일을 Azure Digital Twins 서비스 인스턴스에 업로드합니다.

앞에서 추가한 인증 코드 아래에 다음 코드를 붙여넣습니다.

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

명령 창에서 다음 명령을 사용하여 프로그램을 실행합니다.

dotnet run

이 코드에 도달했음을 나타내는 "모델 업로드"가 출력에 인쇄되지만 업로드 성공 여부를 나타내는 출력은 아직 없습니다.

인스턴스에 성공적으로 업로드된 모든 모델을 보여주는 print 문을 추가하려면 이전 섹션 바로 뒤에 다음 코드를 추가합니다.

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

이 새 코드를 테스트하기 위해 프로그램을 다시 실행하기 전에, 이 프로그램을 마지막으로 실행할 때 모델을 업로드했음을 기억하세요. Azure Digital Twins에서는 동일한 모델을 두 번 업로드할 수 없으므로 동일한 모델을 다시 업로드하려고 하면 프로그램에서 예외를 throw해야 합니다.

이 정보를 염두에 두고 명령 창에서 다음 명령을 사용하여 프로그램을 다시 실행합니다.

dotnet run

프로그램에서 예외가 throw됩니다. 이미 업로드된 모델을 업로드하려고 하면 서비스에서 REST API를 통해 "잘못된 요청" 오류를 반환합니다. 따라서 Azure Digital Twins 클라이언트 SDK는 성공 이외의 모든 서비스 반환 코드에 대해 예외를 throw합니다.

다음 섹션에서는 이러한 예외와 코드에서 이 예외를 처리하는 방법에 대해 설명합니다.

오류 catch

프로그램의 크래시를 방지하기 위해 모델 업로드 코드에 예외 코드를 추가할 수 있습니다. try/catch 처리기에서 기존 클라이언트 호출 await client.CreateModelsAsync(typeList)를 다음과 같이 래핑합니다.

try
{
    await client.CreateModelsAsync(models);
    Console.WriteLine("Models uploaded to the instance:");
}
catch (RequestFailedException e)
{
    Console.WriteLine($"Upload model error: {e.Status}: {e.Message}");
}

명령 창에서 dotnet run을 사용하여 프로그램을 다시 실행합니다. ModelIdAlreadyExists를 나타내는 오류 코드를 포함하여 모델 업로드 문제에 대한 자세한 내용을 다시 확인할 수 있습니다.

이 자습서에서는 이 지점부터 try/catch 처리기에서 서비스 메서드에 대한 모든 호출을 래핑합니다.

디지털 트윈 만들기

Azure Digital Twins에 모델을 업로드했으므로 이제 이 모델 정의를 사용하여 디지털 트윈을 만들 수 있습니다. 디지털 트윈은 모델의 인스턴스이며, 비즈니스 환경 내의 엔터티(예: 농장의 센서, 건물의 방, 자동차의 조명)를 나타냅니다. 이 섹션에서는 이전에 업로드한 모델에 따라 몇 개의 디지털 트윈을 만듭니다.

Main 메서드의 끝에 다음 코드를 추가하여 이 모델을 기반으로 세 개의 디지털 트윈을 만들고 초기화합니다.

var twinData = new BasicDigitalTwin();
twinData.Metadata.ModelId = "dtmi:example:SampleModel;1";
twinData.Contents.Add("data", $"Hello World!");

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

명령 창에서 dotnet run을 사용하여 프로그램을 실행합니다. 출력에서 sampleTwin-0, sampleTwin-1 및 sampleTwin-2가 생성된 인쇄 메시지를 찾습니다.

그런 다음, 프로그램을 다시 실행합니다.

트윈이 두 번째로 만들어지는 경우, 첫 번째 실행 후에 트윈이 이미 존재해도 오류가 throw되지 않습니다. 모델 생성과 달리 트윈 생성은 REST 수준에서 upsert 의미 체계를 사용하는 PUT 호출입니다. 이러한 유형의 REST 호출을 사용하는 경우 트윈이 이미 있을 때 동일한 트윈을 다시 만들려고 하면 원래 트윈으로 바뀝니다. 오류가 throw되지 않습니다.

관계 만들기

다음으로, 앞에서 만든 트윈 간의 관계를 만들어 트윈 그래프로 연결할 수 있습니다. 트윈 그래프는 전체 환경을 나타내는 데 사용됩니다.

Main 메서드 아래의 Program 클래스에 새 정적 메서드를 추가합니다(이제 코드에는 두 가지 메서드가 있음).

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

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

다음으로, 다음 코드를 Main 메서드의 끝에 추가하여 CreateRelationship 메서드를 호출하고 방금 작성한 코드를 사용합니다.

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

명령 창에서 dotnet run을 사용하여 프로그램을 실행합니다. 출력에서 두 관계가 성공적으로 생성되었음을 알리는 print 문을 찾습니다.

Azure Digital Twins에서는 동일한 ID를 가진 다른 관계가 이미 있는 경우 이러한 관계를 만들 수 없으므로, 프로그램을 여러 번 실행하면 관계 만들기에 대한 예외가 표시됩니다. 이 코드는 예외를 catch하여 무시합니다.

관계 목록

다음으로 추가할 코드를 사용하면 내가 만든 관계의 목록을 볼 수 있습니다.

Program 클래스에 다음 새 메서드를 추가합니다.

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

그런 다음, Main 메서드의 끝에 다음 코드를 추가하여 ListRelationships 코드를 호출합니다.

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

명령 창에서 dotnet run을 사용하여 프로그램을 실행합니다. 출력 문에서 만든 모든 관계의 목록이 다음과 같이 표시됩니다.

Screenshot of a console showing the program output, which results in a message that lists the twin relationships.

디지털 트윈 쿼리

Azure Digital Twins의 주요 기능은 환경에 대한 질문에 답하도록 쉽고 효율적으로 트윈 그래프를 쿼리하는 기능입니다.

이 자습서에서 추가할 코드의 마지막 섹션은 Azure Digital Twins 인스턴스에 대해 쿼리를 실행합니다. 이 예제에 사용된 쿼리는 인스턴스의 모든 디지털 트윈을 반환합니다.

JsonSerializer 클래스를 사용하여 디지털 트윈 정보를 제공할 수 있도록 이 using 문을 추가합니다.

using System.Text.Json;

그런 다음, Main 메서드의 끝에 다음 코드를 추가합니다.

// Run a query for all twins
string query = "SELECT * FROM digitaltwins";
AsyncPageable<BasicDigitalTwin> queryResult = client.QueryAsync<BasicDigitalTwin>(query);

await foreach (BasicDigitalTwin twin in queryResult)
{
    Console.WriteLine(JsonSerializer.Serialize(twin));
    Console.WriteLine("---------------");
}

명령 창에서 dotnet run을 사용하여 프로그램을 실행합니다. 이 인스턴스의 모든 디지털 트윈이 출력에 표시됩니다.

참고 항목

그래프의 데이터를 변경한 후 변경 사항이 쿼리에 반영될 때까지 대기 시간은 최대 10초일 수 있습니다.

DigitalTwins API는 변경 사항을 즉시 반영하므로 즉각적인 응답이 필요한 경우 API 요청(DigitalTwins GetById)이나 SDK 호출(GetDigitalTwin)을 사용하여 쿼리 대신 트윈 데이터를 가져옵니다.

전체 코드 예제

자습서의 이 지점에는 Azure Digital Twins에 대한 기본 작업을 수행할 수 있는 전체 클라이언트 앱이 있습니다. 참조용으로 Program.cs의 프로그램 코드 전체가 아래에 나와 있습니다.

using System;
// <Azure_Digital_Twins_dependencies>
using Azure.DigitalTwins.Core;
using Azure.Identity;
// </Azure_Digital_Twins_dependencies>
// <Model_dependencies>
using System.Threading.Tasks;
using System.IO;
using System.Collections.Generic;
using Azure;
// </Model_dependencies>
// <Query_dependencies>
using System.Text.Json;
// </Query_dependencies>

namespace DigitalTwins_Samples
{
    class DigitalTwinsClientAppSample
    {
        // <Async_signature>
        static async Task Main(string[] args)
        {
        // </Async_signature>
            Console.WriteLine("Hello World!");
            // <Authentication_code>
            string adtInstanceUrl = "https://<your-Azure-Digital-Twins-instance-hostName>"; 
            
            var credential = new DefaultAzureCredential();
            var client = new DigitalTwinsClient(new Uri(adtInstanceUrl), credential);
            Console.WriteLine($"Service client created – ready to go");
            // </Authentication_code>

            // <Model_code>
            Console.WriteLine();
            Console.WriteLine("Upload a model");
            string dtdl = File.ReadAllText("SampleModel.json");
            var models = new List<string> { dtdl };

            // Upload the model to the service
            // <Model_try_catch>
            try
            {
                await client.CreateModelsAsync(models);
                Console.WriteLine("Models uploaded to the instance:");
            }
            catch (RequestFailedException e)
            {
                Console.WriteLine($"Upload model error: {e.Status}: {e.Message}");
            }
            // </Model_try_catch>

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

            // <Initialize_twins>
            var twinData = new BasicDigitalTwin();
            twinData.Metadata.ModelId = "dtmi:example:SampleModel;1";
            twinData.Contents.Add("data", $"Hello World!");
            
            string prefix = "sampleTwin-";
            for (int i = 0; i < 3; i++)
            {
                try
                {
                    twinData.Id = $"{prefix}{i}";
                    await client.CreateOrReplaceDigitalTwinAsync<BasicDigitalTwin>(twinData.Id, twinData);
                    Console.WriteLine($"Created twin: {twinData.Id}");
                }
                catch(RequestFailedException e)
                {
                    Console.WriteLine($"Create twin error: {e.Status}: {e.Message}");
                }
            }
            // </Initialize_twins>

            // <Use_create_relationship>
            // Connect the twins with relationships
            await CreateRelationshipAsync(client, "sampleTwin-0", "sampleTwin-1");
            await CreateRelationshipAsync(client, "sampleTwin-0", "sampleTwin-2");
            // </Use_create_relationship>

            // <Use_list_relationships>
            //List the relationships
            await ListRelationshipsAsync(client, "sampleTwin-0");
            // </Use_list_relationships>

            // <Query_twins>
            // Run a query for all twins
            string query = "SELECT * FROM digitaltwins";
            AsyncPageable<BasicDigitalTwin> queryResult = client.QueryAsync<BasicDigitalTwin>(query);
            
            await foreach (BasicDigitalTwin twin in queryResult)
            {
                Console.WriteLine(JsonSerializer.Serialize(twin));
                Console.WriteLine("---------------");
            }
            // </Query_twins>
        }

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

리소스 정리

이 자습서를 완료한 후 다음에 수행하려는 작업에 따라 제거할 리소스를 선택할 수 있습니다.

  • 다음 자습서로 계속 진행하려는 경우 이 자습서에서 사용된 인스턴스를 다음 자습서에서 다시 사용할 수 있습니다. 여기서 설정한 Azure Digital Twines 리소스를 유지하고 이 섹션의 나머지 부분을 건너뛸 수 있습니다.
  • 이 문서에서 Azure Digital Twins 인스턴스를 계속 사용하지만 해당 모델, 트윈 및 관계를 모두 지우려면 다음 az dt job deletion CLI 명령을 실행합니다.

    az dt job deletion create -n <name-of-Azure-Digital-Twins-instance> -y
    

    이러한 요소의 일부를 삭제하려는 경우 az dt twin relationship delete, az dt twin delete, az dt model delete 명령을 사용하여 제거하려는 요소만 선택적으로 삭제할 수 있습니다.

  • 이 자습서에서 만든 리소스가 필요하지 않으면 az group delete CLI 명령을 사용하여 이 문서의 Azure Digital Twins 인스턴스 및 기타 모든 리소스를 삭제할 수 있습니다. 이는 리소스 그룹의 모든 Azure 리소스와 리소스 그룹 자체를 삭제합니다.

    Important

    리소스 그룹을 삭제하면 다시 되돌릴 수 없습니다. 리소스 그룹 및 그 안에 포함된 모든 리소스가 영구적으로 삭제됩니다. 잘못된 리소스 그룹 또는 리소스를 자동으로 삭제하지 않도록 해야 합니다.

    Azure Cloud Shell 또는 로컬 CLI 창을 열고, 다음 명령을 실행하여 리소스 그룹과 이 그룹에 포함된 모든 항목을 삭제합니다.

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

로컬 머신에서 프로젝트 폴더를 삭제해야 할 수도 있습니다.

다음 단계

이 자습서에서는 .NET 콘솔 클라이언트 애플리케이션을 처음부터 새로 만들었습니다. Azure Digital Twins 인스턴스에서 기본 작업을 수행하기 위해 이 클라이언트 앱의 코드를 작성했습니다.

다음 자습서를 계속 진행하여 이러한 샘플 클라이언트 앱으로 수행할 수 있는 작업을 살펴봅니다.