İlişkileri kullanarak dijital ikiz grafiğini yönetme

Azure Digital Twins'in kalbi, tüm ortamınızı temsil eden ikiz grafıdır. İkiz grafı, ilişkiler aracılığıyla bağlanan tek tek dijital ikizlerden oluşur. Bu makalede ilişkilerin ve grafiğin bir bütün olarak yönetilmesine odaklanmaktadır; tek tek dijital ikizlerle çalışmak için bkz . Dijital ikizleri yönetme.

Çalışan bir Azure Digital Twins örneğiniz olduğunda ve istemci uygulamanızda kimlik doğrulama kodunu ayarladıktan sonra, bir Azure Digital Twins örneğinde dijital ikizleri ve bunların ilişkilerini oluşturabilir, değiştirebilir ve silebilirsiniz.

Önkoşullar

Bu makalede Azure Digital Twins ile çalışmak için bir Azure Digital Twins örneğine ve bunu kullanmak için gerekli izinlere sahip olmanız gerekir. Zaten ayarlanmış bir Azure Digital Twins örneğiniz varsa bu örneği kullanabilir ve sonraki bölüme atlayabilirsiniz. Aksi takdirde, Örnek ve kimlik doğrulaması ayarlama başlığındaki yönergeleri izleyin. Yönergeler, her adımı başarıyla tamamladığınızdan emin olmanıza yardımcı olacak bilgiler içerir.

Örneğinizi ayarladıktan sonra, örneğin ana bilgisayar adını not edin. Konak adını Azure portalında bulabilirsiniz.

Geliştirici arabirimleri

Bu makalede .NET (C#) SDK'sını kullanarak farklı yönetim işlemlerinin nasıl tamamlandığı vurgulanmaktadır. Bu yönetim çağrılarını Azure Digital Twins API'leri ve SDK'larında açıklanan diğer dil SDK'larını kullanarak da oluşturabilirsiniz.

Bu işlemleri tamamlamak için kullanılabilecek diğer geliştirici arabirimleri şunlardır:

Görselleştirme

Azure Digital Twins Gezgini , Azure Digital Twins grafınızdaki verileri keşfetmeye yönelik görsel bir araçtır. Modellerinizi, ikizlerinizi ve ilişkilerinizi görüntülemek, sorgulamak ve düzenlemek için gezgini kullanabilirsiniz.

Azure Digital Twins Gezgini aracı hakkında bilgi edinmek için bkz . Azure Digital Twins Gezgini. Özelliklerini kullanma hakkında ayrıntılı adımlar için bkz . Azure Digital Twins Gezgini'ni kullanma.

Görselleştirme şöyle görünür:

Screenshot of Azure Digital Twins Explorer showing sample models and twins.

İlişki oluşturma

İlişkiler, ikiz grafiğinin temelini oluşturan farklı dijital ikizlerin birbirine nasıl bağlanacaklarını açıklar.

Bir (kaynak) ikizden başka bir (hedef) ikize oluşturulabilen ilişki türleri, kaynak ikizin DTDL modelinin bir parçası olarak tanımlanır. SDK çağrısını CreateOrReplaceRelationshipAsync() ikizler ve DTDL tanımını izleyen ilişki ayrıntılarıyla kullanarak bir ilişkinin örneğini oluşturabilirsiniz.

İlişki oluşturmak için şunları belirtmeniz gerekir:

  • Kaynak ikiz kimliği (srcId aşağıdaki kod örneğinde): İlişkinin kaynaklandığı ikizin kimliği.
  • Hedef ikiz kimliği (targetId aşağıdaki kod örneğinde): İlişkinin geldiği ikizin kimliği.
  • İlişki adı (relNameaşağıdaki kod örneğinde): İçeren bir şey gibi genel ilişki türü.
  • İlişki kimliği (relIdaşağıdaki kod örneğinde): Bu ilişkinin belirli adı( İlişki1 gibi bir ad).

İlişki kimliği, verilen kaynak ikiz içinde benzersiz olmalıdır. Genel olarak benzersiz olması gerekmez. Örneğin, ikiz Foo için her bir ilişki kimliği benzersiz olmalıdır. Ancak başka bir ikiz Çubuğu, foo ilişkisinin aynı kimliğiyle eşleşen giden bir ilişkiye sahip olabilir.

Aşağıdaki kod örneği, Azure Digital Twins örneğinizde nasıl ilişki oluşturulacağını gösterir. Daha büyük bir program bağlamında görünebilecek özel bir yöntem içinde SDK çağrısını (vurgulanmış) kullanır.

private async static Task CustomMethod_CreateRelationshipAsync(DigitalTwinsClient client, string srcId, string targetId, string relName, IDictionary<string,object> inputProperties)
{
    var relationship = new BasicRelationship
    {
        TargetId = targetId,
        Name = relName,
        Properties = inputProperties
    };

    try
    {
        string relId = $"{srcId}-{relName}->{targetId}";
        await client.CreateOrReplaceRelationshipAsync<BasicRelationship>(srcId, relId, relationship);
        Console.WriteLine($"Created {relName} relationship successfully. Relationship ID is {relId}.");
    }
    catch (RequestFailedException rex)
    {
        Console.WriteLine($"Create relationship error: {rex.Status}:{rex.Message}");
    }

}

Bu özel işlev artık aşağıdaki şekilde bir içerir ilişkisi oluşturmak için çağrılabilir:

await CustomMethod_CreateRelationshipAsync(client, srcId, targetId, "contains", properties);

Birden çok ilişki oluşturmak isterseniz, bağımsız değişkene farklı ilişki türleri geçirerek aynı yönteme yapılan çağrıları yineleyebilirsiniz.

yardımcı sınıfı BasicRelationshiphakkında daha fazla bilgi için bkz . Azure Digital Twins API'leri ve SDK'ları.

İkizler arasında birden çok ilişki oluşturma

İlişkiler şunlardan biri olarak sınıflandırılabilir:

  • Giden ilişkiler: Bu ikize ait olan ve diğer ikizlere bağlanmaya işaret eden ilişkiler. GetRelationshipsAsync() yöntemi, bir ikizin giden ilişkilerini almak için kullanılır.
  • Gelen ilişkiler: "Gelen" bağlantısı oluşturmak için bu ikize işaret eden diğer ikizlere ait ilişkiler. GetIncomingRelationshipsAsync() yöntemi, bir ikizin gelen ilişkilerini almak için kullanılır.

İki ikiz arasında sahip olabileceğiniz ilişkilerin sayısıyla ilgili bir kısıtlama yoktur; ikizler arasında istediğiniz kadar ilişki olabilir.

Bu gerçek, iki ikiz arasındaki birkaç farklı ilişki türünü aynı anda ifade edebilirsiniz anlamına gelir. Örneğin, A İkizi hem saklı bir ilişkiye hem de B İkizi ile üretilen ilişkiye sahip olabilir.

İsterseniz, aynı iki ikiz arasında aynı ilişki türünde birden çok örnek bile oluşturabilirsiniz. Bu örnekte, ilişkilerin farklı ilişki kimlikleri olduğu sürece, İkiz A'nın İkiz B ile iki farklı saklı ilişkisi olabilir.

Dekont

ve ilişkileri için DTDL öznitelikleri minMultiplicitymaxMultiplicity şu anda Azure Digital Twins'de desteklenmemektedir; modelin bir parçası olarak tanımlansalar bile hizmet tarafından zorunlu tutulmaz. Daha fazla bilgi için bkz . Hizmete özgü DTDL notları.

İşleri İçeri Aktar API'siyle toplu ilişkiler oluşturma

tek bir API çağrısında aynı anda birden çok ilişki oluşturmak için İşleri İçeri Aktar API'sini kullanabilirsiniz. Bu yöntem, Azure Blob Depolama kullanılmasının yanı sıra ilişkiler ve toplu işler için Azure Digital Twins örneğinizde yazma izinleri gerektirir.

Bahşiş

İşleri İçeri Aktar API'si ayrıca modellerin ve ikizlerin aynı çağrıda içeri aktarılarak grafın tüm bölümlerinin aynı anda oluşturulmasına da olanak tanır. Bu işlem hakkında daha fazla bilgi için bkz . İçeri Aktarma İşleri API'siyle modelleri, ikizleri ve ilişkileri toplu olarak karşıya yükleme.

İlişkileri toplu olarak içeri aktarmak için ilişkilerinizi (ve toplu içeri aktarma işine dahil olan diğer kaynakları) NDJSON dosyası olarak yapılandırmanız gerekir. bölümü Relationships , bölümden Twins sonra gelir ve dosyadaki son graf verileri bölümü haline gelir. Dosyada tanımlanan ilişkiler, bu dosyada tanımlanan veya örnekte zaten var olan ikizlere başvurabilir ve isteğe bağlı olarak ilişkilerin sahip olduğu tüm özelliklerin başlatılmasını içerebilir.

İçeri Aktarma İşleri API'sine giriş bölümünde örnek bir içeri aktarma dosyası ve bu dosyaları oluşturmak için örnek bir proje görüntüleyebilirsiniz.

Ardından, dosyanın Azure Blob Depolama'daki bir ekleme blobuna yüklenmesi gerekir. Azure depolama kapsayıcısı oluşturma yönergeleri için bkz . Kapsayıcı oluşturma. Ardından, tercih ettiğiniz karşıya yükleme yöntemini kullanarak dosyayı karşıya yükleyin (bazı seçenekler AzCopy komutu, Azure CLI veya Azure portalıdır).

NDJSON dosyası kapsayıcıya yüklendikten sonra url'sini blob kapsayıcısına alın. Bu değeri daha sonra toplu içeri aktarma API çağrısının gövdesinde kullanacaksınız.

Azure portalında blob dosyasının URL değerini gösteren ekran görüntüsü aşağıdadır:

Screenshot of the Azure portal showing the URL of a file in a storage container.

Ardından, dosya bir İçeri Aktarma İşleri API çağrısında kullanılabilir. Giriş dosyasının blob depolama URL'sini ve hizmet tarafından oluşturulduğunda çıkış günlüğünün nerede depolanmasını istediğinizi belirtmek için yeni bir blob depolama URL'si sağlayacaksınız.

Liste ilişkileri

Tek bir ilişkinin özelliklerini listeleme

İlişki verilerini istediğiniz türe seri durumdan çıkarabilirsiniz. İlişkiye temel erişim için türünü BasicRelationshipkullanın. BasicRelationship Yardımcı sınıfı, ilişkide tanımlanan özelliklere bir IDictionary<string, object>aracılığıyla erişmenizi de sağlar. Özellikleri listelemek için şunları kullanabilirsiniz:

public async Task ListRelationshipProperties(DigitalTwinsClient client, string twinId, string relId, BasicDigitalTwin twin)
{

    var res = await client.GetRelationshipAsync<BasicRelationship>(twinId, relId);
    BasicRelationship rel = res.Value;
    Console.WriteLine($"Relationship Name: {rel.Name}");
    foreach (string prop in rel.Properties.Keys)
    {
        if (twin.Contents.TryGetValue(prop, out object value))
        {
            Console.WriteLine($"Property '{prop}': {value}");
        }
    }
}

Dijital ikizden giden ilişkileri listeleme

Grafikteki belirli bir ikizin giden ilişkileri listesine erişmek için aşağıdaki yöntemi kullanabilirsiniz GetRelationships() :

AsyncPageable<BasicRelationship> rels = client.GetRelationshipsAsync<BasicRelationship>(dtId);

Bu yöntem, çağrının zaman uyumlu veya zaman uyumsuz sürümünü kullanıp kullanmadığınıza bağlı olarak veya Azure.Pageable<T>Azure.AsyncPageable<T>döndürür.

aşağıda ilişkilerin listesini alan bir örnek verilmiştir. Daha büyük bir program bağlamında görünebilecek özel bir yöntem içinde SDK çağrısını (vurgulanmış) kullanır.

private static async Task<List<BasicRelationship>> CustomMethod_FindOutgoingRelationshipsAsync(DigitalTwinsClient client, string dtId)
{
    // Find the relationships for the twin
    
    try
    {
        // GetRelationshipsAsync will throw if an error occurs
        AsyncPageable<BasicRelationship> rels = client.GetRelationshipsAsync<BasicRelationship>(dtId);
        var results = new List<BasicRelationship>();
        await foreach (BasicRelationship rel in rels)
        {
            results.Add(rel);
            Console.WriteLine($"Found relationship: {rel.Id}");

            //Print its properties
            Console.WriteLine($"Relationship properties:");
            foreach(KeyValuePair<string, object> property in rel.Properties)
            {
                Console.WriteLine("{0} = {1}", property.Key, property.Value);
            }
        }

        return results;
    }
    catch (RequestFailedException ex)
    {
        Console.WriteLine($"*** Error {ex.Status}/{ex.ErrorCode} retrieving relationships for {dtId} due to {ex.Message}");
        return null;
    }
}

Artık ikizlerin giden ilişkilerini görmek için bu özel yöntemi çağırabilirsiniz:

await CustomMethod_FindOutgoingRelationshipsAsync(client, twin_Id);

Döndürülen ilişkideki alanı okuyarak target ve bir sonraki çağrısınızın kimliği olarak kullanarak grafınızdaki diğer ikizlere GetDigitalTwin()gitmek için alınan ilişkileri kullanabilirsiniz.

Dijital ikizle gelen ilişkileri listeleme

Azure Digital Twins ayrıca belirli bir ikizle gelen tüm ilişkileri bulmak için bir SDK çağrısına sahiptir. Bu SDK genellikle ters gezinti için veya ikiz silerken kullanışlıdır.

Dekont

IncomingRelationship çağrıları ilişkinin tüm gövdesini döndürmez. sınıfı hakkında IncomingRelationship daha fazla bilgi için başvuru belgelerine bakın.

Önceki bölümde yer alan kod örneği, bir ikizden giden ilişkileri bulmaya odaklanmıştır. Aşağıdaki örnek benzer şekilde yapılandırılmıştır, ancak bunun yerine ikizle gelen ilişkileri bulur. Bu örnek, daha büyük bir program bağlamında görünebilecek özel bir yöntem içinde SDK çağrısını (vurgulanmış) da kullanır.

private static async Task<List<IncomingRelationship>> CustomMethod_FindIncomingRelationshipsAsync(DigitalTwinsClient client, string dtId)
{
    // Find the relationships for the twin
    
    try
    {
        // GetRelationshipsAsync will throw an error if a problem occurs
        AsyncPageable<IncomingRelationship> incomingRels = client.GetIncomingRelationshipsAsync(dtId);

        var results = new List<IncomingRelationship>();
        await foreach (IncomingRelationship incomingRel in incomingRels)
        {
            results.Add(incomingRel);
            Console.WriteLine($"Found incoming relationship: {incomingRel.RelationshipId}");

            //Print its properties
            Response<BasicRelationship> relResponse = await client.GetRelationshipAsync<BasicRelationship>(incomingRel.SourceId, incomingRel.RelationshipId);
            BasicRelationship rel = relResponse.Value;
            Console.WriteLine($"Relationship properties:");
            foreach(KeyValuePair<string, object> property in rel.Properties)
            {
                Console.WriteLine("{0} = {1}", property.Key, property.Value);
            }
        }
        return results;
    }
    catch (RequestFailedException ex)
    {
        Console.WriteLine($"*** Error {ex.Status}/{ex.ErrorCode} retrieving incoming relationships for {dtId} due to {ex.Message}");
        return null;
    }
}

Artık ikizlerin gelen ilişkilerini görmek için bu özel yöntemi çağırabilirsiniz:

await CustomMethod_FindIncomingRelationshipsAsync(client, twin_Id);

Tüm ikiz özelliklerini ve ilişkilerini listeleme

Bir ikize giden ve gelen ilişkileri listelemek için yukarıdaki yöntemleri kullanarak, ikizin özellikleri ve her iki ilişki türü de dahil olmak üzere tam ikiz bilgilerini yazdıran bir yöntem oluşturabilirsiniz. Bu amaçla yukarıdaki özel yöntemlerin nasıl birleştirildiğine ilişkin örnek bir özel yöntem aşağıda verilmiştir.

private static async Task CustomMethod_FetchAndPrintTwinAsync(string twin_Id, DigitalTwinsClient client)
{
    Response<BasicDigitalTwin> res = await client.GetDigitalTwinAsync<BasicDigitalTwin>(twin_Id);
    await CustomMethod_FindOutgoingRelationshipsAsync(client, twin_Id);
    await CustomMethod_FindIncomingRelationshipsAsync(client, twin_Id);

    return;
}

Artık bu özel işlevi şu şekilde çağırabilirsiniz:

await CustomMethod_FetchAndPrintTwinAsync(srcId, client);

İlişkileri güncelleştirme

İlişkiler yöntemi kullanılarak UpdateRelationship güncelleştirilir.

Dekont

Bu yöntem, bir ilişkinin özelliklerini güncelleştirmek içindir. İlişkinin kaynak ikizini veya hedef ikizini değiştirmeniz gerekiyorsa, ilişkiyi silmeniz ve yeni ikizleri kullanarak yeniden oluşturmanız gerekir.

İstemci çağrısı için gerekli parametreler şunlardır:

Bu yöntemin nasıl kullanılacağını gösteren örnek kod parçacığı aşağıda verilmiştır. Bu örnek, daha büyük bir program bağlamında görünebilen özel bir yöntem içinde SDK çağrısını (vurgulanmış) kullanır.

private async static Task CustomMethod_UpdateRelationshipAsync(DigitalTwinsClient client, string srcId, string relId, Azure.JsonPatchDocument updateDocument)
{

    try
    {
        await client.UpdateRelationshipAsync(srcId, relId, updateDocument);
        Console.WriteLine($"Successfully updated {relId}");
    }
    catch (RequestFailedException rex)
    {
        Console.WriteLine($"Update relationship error: {rex.Status}:{rex.Message}");
    }

}

Burada, bir özelliği güncelleştirmek için bilgileri içeren bir JSON Patch belgesi geçirerek bu özel yönteme yapılan bir çağrı örneği verilmiştir.

var updatePropertyPatch = new JsonPatchDocument();
updatePropertyPatch.AppendAdd("/ownershipUser", "ownershipUser NEW value");
await CustomMethod_UpdateRelationshipAsync(client, srcId, $"{srcId}-contains->{targetId}", updatePropertyPatch);

İlişkileri silme

İlk parametre kaynak ikizini (ilişkinin kaynaklandığı ikiz) belirtir. Diğer parametre ise ilişki kimliğidir. İlişki kimlikleri yalnızca ikiz kapsamında benzersiz olduğundan hem ikiz kimliğine hem de ilişki kimliğine ihtiyacınız vardır.

Bu yöntemin nasıl kullanılacağını gösteren örnek kod aşağıda verilmiştır. Bu örnek, daha büyük bir program bağlamında görünebilen özel bir yöntem içinde SDK çağrısını (vurgulanmış) kullanır.

private static async Task CustomMethod_DeleteRelationshipAsync(DigitalTwinsClient client, string srcId, string relId)
{
    try
    {
        Response response = await client.DeleteRelationshipAsync(srcId, relId);
        await CustomMethod_FetchAndPrintTwinAsync(srcId, client);
        Console.WriteLine("Deleted relationship successfully");
    }
    catch (RequestFailedException e)
    {
        Console.WriteLine($"Error {e.ErrorCode}");
    }
}

Şimdi aşağıdaki gibi bir ilişkiyi silmek için bu özel yöntemi çağırabilirsiniz:

await CustomMethod_DeleteRelationshipAsync(client, srcId, $"{srcId}-contains->{targetId}");

Dekont

Bir örnekteki tüm modelleri, ikizleri ve ilişkileri aynı anda silmek istiyorsanız, İşleri Sil API'sini kullanın.

Aynı anda birden çok grafik öğesi oluşturma

Bu bölümde, modelleri, ikizleri ve ilişkileri tek tek karşıya yüklemek için tek tek API çağrıları kullanmak yerine aynı anda birden çok öğe içeren bir grafik oluşturma stratejileri açıklanmaktadır.

İşleri İçeri Aktarma API'siyle modelleri, ikizleri ve ilişkileri toplu olarak karşıya yükleme

Tek bir API çağrısında örneğinize birden çok model, ikiz ve ilişki yüklemek için İşleri İçeri Aktar API'sini kullanabilir ve grafı tek seferde etkili bir şekilde oluşturabilirsiniz. Bu yöntem, Azure Blob Depolama kullanılmasının yanı sıra Azure Digital Twins örneğinizde grafik öğeleri (modeller, ikizler ve ilişkiler) ve toplu işler için yazma izinleri gerektirir.

Kaynakları toplu olarak içeri aktarmak için, kaynaklarınızın ayrıntılarını içeren bir NDJSON dosyası oluşturarak başlayın. Dosya bir Header bölümle başlar ve ardından isteğe bağlı , Twinsve Relationshipsbölümleriyle Modelsbaşlar. Dosyaya üç grafik verisi türünü de eklemeniz gerekmez, ancak mevcut bölümlerin bu sıraya uyması gerekir. Dosyada tanımlanan ikizler, bu dosyada tanımlanan veya örnekte zaten mevcut olan modellere başvurabilir ve isteğe bağlı olarak ikizin özelliklerinin başlatılmasını içerebilir. Dosyada tanımlanan ilişkiler, bu dosyada tanımlanan veya örnekte zaten var olan ikizlere başvurabilir ve isteğe bağlı olarak ilişki özelliklerinin başlatılmasını içerebilir.

İçeri Aktarma İşleri API'sine giriş bölümünde örnek bir içeri aktarma dosyası ve bu dosyaları oluşturmak için örnek bir proje görüntüleyebilirsiniz.

Ardından, dosyanın Azure Blob Depolama'daki bir ekleme blobuna yüklenmesi gerekir. Azure depolama kapsayıcısı oluşturma yönergeleri için bkz . Kapsayıcı oluşturma. Ardından, tercih ettiğiniz karşıya yükleme yöntemini kullanarak dosyayı karşıya yükleyin (bazı seçenekler AzCopy komutu, Azure CLI veya Azure portalıdır).

NDJSON dosyası kapsayıcıya yüklendikten sonra url'sini blob kapsayıcısına alın. Bu değeri daha sonra toplu içeri aktarma API çağrısının gövdesinde kullanacaksınız.

Azure portalında blob dosyasının URL değerini gösteren ekran görüntüsü aşağıdadır:

Screenshot of the Azure portal showing the URL of a file in a storage container.

Ardından, dosya bir İçeri Aktarma İşleri API çağrısında kullanılabilir. Giriş dosyasının blob depolama URL'sini ve hizmet tarafından oluşturulduğunda çıkış günlüğünün nerede depolanmasını istediğinizi belirtmek için yeni bir blob depolama URL'si sağlayacaksınız.

Azure Digital Twins Gezgini ile grafı içeri aktarma

Azure Digital Twins Gezgini , ikiz grafınızı görüntülemeye ve bunlarla etkileşime geçişe yönelik görsel bir araçtır. Bir grafik dosyasını birden çok model, ikiz ve ilişki içerebilen JSON veya Excel biçiminde içeri aktarma özelliği içerir.

Bu özelliği kullanma hakkında ayrıntılı bilgi için Azure Digital Twins Gezgini belgelerindeki Grafı içeri aktarma bölümüne bakın.

CSV dosyasından ikizler ve ilişkiler oluşturma

Bazen, farklı bir veritabanında veya bir elektronik tabloda ya da CSV dosyasında depolanan verilerden ikiz hiyerarşileri oluşturmanız gerekebilir. Bu bölümde, csv dosyasındaki verilerin nasıl okunacağı ve bu dosyadan bir ikiz grafı nasıl oluşturulacağı gösterilmektedir.

Bir dizi dijital ikiz ve ilişkiyi açıklayan aşağıdaki veri tablosunu göz önünde bulundurun. Bu dosyada başvuruda bulunılan modellerin Azure Digital Twins örneğinde zaten mevcut olması gerekir.

Model Kimliği İkiz Kimliği (benzersiz olmalıdır) İlişki adı Hedef ikiz kimliği İkiz başlatma verileri
dtmi:example:Floor; 1 Kat1 içerir Oda1
dtmi:example:Floor; 1 Floor0 içerir Oda0
dtmi:example:Room; 1 Oda1 {"Sıcaklık": 80}
dtmi:example:Room; 1 Oda0 {"Sıcaklık": 70}

Bu verileri Azure Digital Twins'e aktarmanın bir yolu tabloyu CSV dosyasına dönüştürmektir. Tablo dönüştürüldükten sonra, dosyayı ikizler ve ilişkiler oluşturmak için komutlara yorumlamak için kod yazılabilir. Aşağıdaki kod örneği, CSV dosyasındaki verileri okumayı ve Azure Digital Twins'de ikiz grafı oluşturmayı gösterir.

Aşağıdaki kodda, CSV dosyasına data.csv adı verilir ve Azure Digital Twins örneğinizin ana bilgisayar adını temsil eden bir yer tutucu vardır. Örnek ayrıca bu işleme yardımcı olmak için projenize ekleyebileceğiniz çeşitli paketleri de kullanır.

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Azure;
using Azure.DigitalTwins.Core;
using Azure.Identity;

namespace creating_twin_graph_from_csv
{
    class Program
    {
        static async Task Main(string[] args)
        {
            var relationshipRecordList = new List<BasicRelationship>();
            var twinList = new List<BasicDigitalTwin>();
            List<List<string>> data = ReadData();
            DigitalTwinsClient client = CreateDtClient();

            // Interpret the CSV file data, by each row
            foreach (List<string> row in data)
            {
                string modelID = row.Count > 0 ? row[0].Trim() : null;
                string srcID = row.Count > 1 ? row[1].Trim() : null;
                string relName = row.Count > 2 ? row[2].Trim() : null;
                string targetID = row.Count > 3 ? row[3].Trim() : null;
                string initProperties = row.Count > 4 ? row[4].Trim() : null;
                Console.WriteLine($"ModelID: {modelID}, TwinID: {srcID}, RelName: {relName}, TargetID: {targetID}, InitData: {initProperties}");
                var props = new Dictionary<string, object>();
                // Parse properties into dictionary (left out for compactness)
                // ...

                // Null check for source and target IDs
                if (!string.IsNullOrWhiteSpace(srcID) && !string.IsNullOrWhiteSpace(targetID) && !string.IsNullOrWhiteSpace(relName))
                {
                    relationshipRecordList.Add(
                        new BasicRelationship
                        {
                            SourceId = srcID,
                            TargetId = targetID,
                            Name = relName,
                        });
                }

                if (!string.IsNullOrWhiteSpace(srcID) && !string.IsNullOrWhiteSpace(modelID))
                twinList.Add(
                    new BasicDigitalTwin
                    {
                        Id = srcID,
                        Metadata = { ModelId = modelID },
                        Contents = props,
                    });
            }

            // Create digital twins
            foreach (BasicDigitalTwin twin in twinList)
            {
                try
                {
                    await client.CreateOrReplaceDigitalTwinAsync<BasicDigitalTwin>(twin.Id, twin);
                    Console.WriteLine("Twin is created");
                }
                catch (RequestFailedException ex)
                {
                    Console.WriteLine($"Error {ex.Status}: {ex.Message}");
                }
            }

            // Create relationships between the twins
            foreach (BasicRelationship rec in relationshipRecordList)
            {
                string relId = $"{rec.SourceId}-{rec.Name}->{rec.TargetId}";
                try
                {
                    await client.CreateOrReplaceRelationshipAsync<BasicRelationship>(rec.SourceId, relId, rec);
                    Console.WriteLine($"Relationship {relId} is created");
                }
                catch (RequestFailedException ex)
                {
                    Console.WriteLine($"Error creating relationship {relId}. {ex.Status}: {ex.Message}");
                }
            }
        }

        // Method to ingest data from the CSV file
        public static List<List<string>> ReadData()
        {
            string path = "<path-to>/data.csv";
            string[] lines = System.IO.File.ReadAllLines(path);
            var data = new List<List<string>>();
            int count = 0;
            foreach (string line in lines)
            {
                if (count++ == 0)
                    continue;
                var cols = new List<string>();
                string[] columns = line.Split(',');
                foreach (string column in columns)
                {
                    cols.Add(column);
                }
                data.Add(cols);
            }
            return data;
        }

        // Method to create the digital twins client
        private static DigitalTwinsClient CreateDtClient()
        {
            string adtInstanceUrl = "https://<your-instance-hostname>";
            var credentials = new DefaultAzureCredential();
            return new DigitalTwinsClient(new Uri(adtInstanceUrl), credentials);
        }
    }
}

Çalıştırılabilir ikiz grafı örneği

Aşağıdaki çalıştırılabilir kod parçacığı, dijital ikizler ve ilişkiler dışında bir ikiz grafı oluşturmak için bu makaledeki ilişki işlemlerini kullanır.

Örnek proje dosyalarını ayarlama

Kod parçacığı, Room.json ve Floor.json adlı iki örnek model tanımı kullanır. Model dosyalarını kodunuzda kullanabilmeniz için indirmek için bu bağlantıları kullanarak doğrudan GitHub'daki dosyalara gidin. Ardından, ekranda herhangi bir yere sağ tıklayın, tarayıcınızın sağ tıklama menüsünde Farklı kaydet'i seçin ve dosyaları Room.json ve Floor.json olarak kaydetmek için Farklı Kaydet penceresini kullanın.

Ardından Visual Studio'da veya seçtiğiniz düzenleyicide yeni bir konsol uygulaması projesi oluşturun.

Ardından, çalıştırılabilir örneğin aşağıdaki kodunu projenize kopyalayın:

using System;
using System.Threading.Tasks;
using System.IO;
using System.Collections.Generic;
using Azure;
using Azure.DigitalTwins.Core;
using Azure.Identity;

namespace DigitalTwins_Samples
{
    public class GraphOperationsSample
    {
        public static async Task Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            // Create the Azure Digital Twins client for API calls
            DigitalTwinsClient client = createDtClient();
            Console.WriteLine($"Service client created – ready to go");
            Console.WriteLine();

            // Upload models
            Console.WriteLine($"Upload models");
            Console.WriteLine();
            string dtdl = File.ReadAllText("<path-to>/Room.json");
            string dtdl1 = File.ReadAllText("<path-to>/Floor.json");
            var models = new List<string>
            {
                dtdl,
                dtdl1,
            };
            // Upload the models to the service
            await client.CreateModelsAsync(models);

            // Create new (Floor) digital twin
            var floorTwin = new BasicDigitalTwin();
            string srcId = "myFloorID";
            floorTwin.Metadata.ModelId = "dtmi:example:Floor;1";
            // Floor twins have no properties, so nothing to initialize
            // Create the twin
            await client.CreateOrReplaceDigitalTwinAsync<BasicDigitalTwin>(srcId, floorTwin);
            Console.WriteLine("Twin created successfully");

            // Create second (Room) digital twin
            var roomTwin = new BasicDigitalTwin();
            string targetId = "myRoomID";
            roomTwin.Metadata.ModelId = "dtmi:example:Room;1";
            // Initialize properties
            roomTwin.Contents.Add("Temperature", 35.0);
            roomTwin.Contents.Add("Humidity", 55.0);
            // Create the twin
            await client.CreateOrReplaceDigitalTwinAsync<BasicDigitalTwin>(targetId, roomTwin);
            
            // Create relationship between them
            var properties = new Dictionary<string, object>
            {
                { "ownershipUser", "ownershipUser original value" },
            };
            // <UseCreateRelationship>
            await CustomMethod_CreateRelationshipAsync(client, srcId, targetId, "contains", properties);
            // </UseCreateRelationship>
            Console.WriteLine();

            // Update relationship's Name property
            // <UseUpdateRelationship>
            var updatePropertyPatch = new JsonPatchDocument();
            updatePropertyPatch.AppendAdd("/ownershipUser", "ownershipUser NEW value");
            await CustomMethod_UpdateRelationshipAsync(client, srcId, $"{srcId}-contains->{targetId}", updatePropertyPatch);
            // </UseUpdateRelationship>
            Console.WriteLine();

            //Print twins and their relationships
            Console.WriteLine("--- Printing details:");
            Console.WriteLine($"Outgoing relationships from source twin, {srcId}:");
            // <UseFetchAndPrint>
            await CustomMethod_FetchAndPrintTwinAsync(srcId, client);
            // </UseFetchAndPrint>
            Console.WriteLine();
            Console.WriteLine($"Incoming relationships to target twin, {targetId}:");
            await CustomMethod_FetchAndPrintTwinAsync(targetId, client);
            Console.WriteLine("--------");
            Console.WriteLine();

            // Delete the relationship
            // <UseDeleteRelationship>
            await CustomMethod_DeleteRelationshipAsync(client, srcId, $"{srcId}-contains->{targetId}");
            // </UseDeleteRelationship>
            Console.WriteLine();

            // Print twins and their relationships again
            Console.WriteLine("--- Printing details (after relationship deletion):");
            Console.WriteLine("Outgoing relationships from source twin:");
            await CustomMethod_FetchAndPrintTwinAsync(srcId, client);
            Console.WriteLine();
            Console.WriteLine("Incoming relationships to target twin:");
            await CustomMethod_FetchAndPrintTwinAsync(targetId, client);
            Console.WriteLine("--------");
            Console.WriteLine();
        }

        private static DigitalTwinsClient createDtClient()
        {
            string adtInstanceUrl = "https://<your-instance-hostname>";
            var credentials = new DefaultAzureCredential();
            var client = new DigitalTwinsClient(new Uri(adtInstanceUrl), credentials);
            return client;
        }

        // <CreateRelationshipMethod>
        private async static Task CustomMethod_CreateRelationshipAsync(DigitalTwinsClient client, string srcId, string targetId, string relName, IDictionary<string,object> inputProperties)
        {
            var relationship = new BasicRelationship
            {
                TargetId = targetId,
                Name = relName,
                Properties = inputProperties
            };

            try
            {
                string relId = $"{srcId}-{relName}->{targetId}";
                await client.CreateOrReplaceRelationshipAsync<BasicRelationship>(srcId, relId, relationship);
                Console.WriteLine($"Created {relName} relationship successfully. Relationship ID is {relId}.");
            }
            catch (RequestFailedException rex)
            {
                Console.WriteLine($"Create relationship error: {rex.Status}:{rex.Message}");
            }

        }
        // </CreateRelationshipMethod>

        // <UpdateRelationshipMethod>
        private async static Task CustomMethod_UpdateRelationshipAsync(DigitalTwinsClient client, string srcId, string relId, Azure.JsonPatchDocument updateDocument)
        {

            try
            {
                await client.UpdateRelationshipAsync(srcId, relId, updateDocument);
                Console.WriteLine($"Successfully updated {relId}");
            }
            catch (RequestFailedException rex)
            {
                Console.WriteLine($"Update relationship error: {rex.Status}:{rex.Message}");
            }

        }
        // </UpdateRelationshipMethod>

        // <FetchAndPrintMethod>
        private static async Task CustomMethod_FetchAndPrintTwinAsync(string twin_Id, DigitalTwinsClient client)
        {
            Response<BasicDigitalTwin> res = await client.GetDigitalTwinAsync<BasicDigitalTwin>(twin_Id);
            // <UseFindOutgoingRelationships>
            await CustomMethod_FindOutgoingRelationshipsAsync(client, twin_Id);
            // </UseFindOutgoingRelationships>
            // <UseFindIncomingRelationships>
            await CustomMethod_FindIncomingRelationshipsAsync(client, twin_Id);
            // </UseFindIncomingRelationships>

            return;
        }
        // </FetchAndPrintMethod>

        // <FindOutgoingRelationshipsMethod>
        private static async Task<List<BasicRelationship>> CustomMethod_FindOutgoingRelationshipsAsync(DigitalTwinsClient client, string dtId)
        {
            // Find the relationships for the twin
            
            try
            {
                // GetRelationshipsAsync will throw if an error occurs
                // <GetRelationshipsCall>
                AsyncPageable<BasicRelationship> rels = client.GetRelationshipsAsync<BasicRelationship>(dtId);
                // </GetRelationshipsCall>
                var results = new List<BasicRelationship>();
                await foreach (BasicRelationship rel in rels)
                {
                    results.Add(rel);
                    Console.WriteLine($"Found relationship: {rel.Id}");

                    //Print its properties
                    Console.WriteLine($"Relationship properties:");
                    foreach(KeyValuePair<string, object> property in rel.Properties)
                    {
                        Console.WriteLine("{0} = {1}", property.Key, property.Value);
                    }
                }

                return results;
            }
            catch (RequestFailedException ex)
            {
                Console.WriteLine($"*** Error {ex.Status}/{ex.ErrorCode} retrieving relationships for {dtId} due to {ex.Message}");
                return null;
            }
        }
        // </FindOutgoingRelationshipsMethod>

        // <FindIncomingRelationshipsMethod>
        private static async Task<List<IncomingRelationship>> CustomMethod_FindIncomingRelationshipsAsync(DigitalTwinsClient client, string dtId)
        {
            // Find the relationships for the twin
            
            try
            {
                // GetRelationshipsAsync will throw an error if a problem occurs
                AsyncPageable<IncomingRelationship> incomingRels = client.GetIncomingRelationshipsAsync(dtId);

                var results = new List<IncomingRelationship>();
                await foreach (IncomingRelationship incomingRel in incomingRels)
                {
                    results.Add(incomingRel);
                    Console.WriteLine($"Found incoming relationship: {incomingRel.RelationshipId}");

                    //Print its properties
                    Response<BasicRelationship> relResponse = await client.GetRelationshipAsync<BasicRelationship>(incomingRel.SourceId, incomingRel.RelationshipId);
                    BasicRelationship rel = relResponse.Value;
                    Console.WriteLine($"Relationship properties:");
                    foreach(KeyValuePair<string, object> property in rel.Properties)
                    {
                        Console.WriteLine("{0} = {1}", property.Key, property.Value);
                    }
                }
                return results;
            }
            catch (RequestFailedException ex)
            {
                Console.WriteLine($"*** Error {ex.Status}/{ex.ErrorCode} retrieving incoming relationships for {dtId} due to {ex.Message}");
                return null;
            }
        }
        // </FindIncomingRelationshipsMethod>

        // <DeleteRelationshipMethod>
        private static async Task CustomMethod_DeleteRelationshipAsync(DigitalTwinsClient client, string srcId, string relId)
        {
            try
            {
                Response response = await client.DeleteRelationshipAsync(srcId, relId);
                await CustomMethod_FetchAndPrintTwinAsync(srcId, client);
                Console.WriteLine("Deleted relationship successfully");
            }
            catch (RequestFailedException e)
            {
                Console.WriteLine($"Error {e.ErrorCode}");
            }
        }
        // </DeleteRelationshipMethod>
    }
}

Dekont

Şu anda sarmalayıcı sınıfını DefaultAzureCredential etkileyen ve kimlik doğrulaması sırasında hataya neden olabilecek bilinen bir sorun vardır. Bu sorunla karşılaşırsanız, çözmek için aşağıdaki isteğe bağlı parametreyle örnek DefaultAzureCredential oluşturmayı deneyebilirsiniz: new DefaultAzureCredential(new DefaultAzureCredentialOptions { ExcludeSharedTokenCacheCredential = true });

Bu sorun hakkında daha fazla bilgi için bkz . Azure Digital Twins bilinen sorunlar.

Projeyi yapılandırma

Ardından, proje kodunuzu yapılandırmak için aşağıdaki adımları tamamlayın:

  1. Daha önce indirdiğiniz Room.json ve Floor.json dosyalarını projenize ekleyin ve programınıza bunları nerede bulacağını söylemek için koddaki yer tutucuları değiştirin<path-to>.

  2. Yer tutucuyu <your-instance-hostname> Azure Digital Twins örneğinizin ana bilgisayar adıyla değiştirin.

  3. Projenize Azure Digital Twins ile çalışmak için gereken iki bağımlılık ekleyin. Birincisi .NET için Azure Digital Twins SDK'sının paketi, ikincisi ise Azure'da kimlik doğrulamasına yardımcı olacak araçlar sağlar.

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

Örneği doğrudan çalıştırmak istiyorsanız yerel kimlik bilgilerini de ayarlamanız gerekir. Sonraki bölümde bu işlem adım adım izlenmiştir.

Yerel Azure kimlik bilgilerini ayarlama

Bu örnek, yerel makinenizde çalıştırdığınızda Azure Digital Twins örneğiyle kullanıcıların kimliğini doğrulamak için DefaultAzureCredential (kitaplığın bir parçasıAzure.Identity) kullanır. bir istemci uygulamasının Azure Digital Twins ile kimlik doğrulaması yapmanın farklı yolları hakkında daha fazla bilgi için bkz . Uygulama kimlik doğrulama kodu yazma.

ileDefaultAzureCredential, örnek yerel ortamınızda yerel Azure CLI'da veya Visual Studio ya da Visual Studio Code'da Azure oturumu açma gibi kimlik bilgilerini arar. Bu nedenle, örneğin kimlik bilgilerini ayarlamak için bu mekanizmalardan biriyle Azure'da yerel olarak oturum açmanız gerekir.

Kod örneklerini çalıştırmak için Visual Studio veya Visual Studio Code kullanıyorsanız, Azure Digital Twins örneğine erişmek için kullanmak istediğiniz Azure kimlik bilgileriyle bu düzenleyicide oturum açtığınızdan emin olun. Yerel CLI penceresi kullanıyorsanız Azure hesabınızda oturum açmak için komutunu çalıştırın az login . Bundan sonra, kod örneğinizi çalıştırdığınızda otomatik olarak kimliğiniz doğrulanmalıdır.

Örneği çalıştırma

Kurulumu tamamladığınıza göre örnek kod projesini çalıştırabilirsiniz.

Programın konsol çıkışı aşağıdadır:

Screenshot of the console output showing the twin details with incoming and outgoing relationships of the twins.

Bahşiş

İkiz grafiği, ikizler arasında ilişki oluşturma kavramıdır. İkiz grafiğin görsel gösterimini görüntülemek istiyorsanız, bu makalenin Görselleştirme bölümüne bakın.

Sonraki adımlar

Azure Digital Twins ikiz grafiğini sorgulama hakkında bilgi edinin: