التشغيل السريع: إنشاء تطبيق API جدول مع حزمة SDK.NET و Azure Cosmos DB

ينطبق على: واجهة برمجة تطبيقات Table

يوضح هذا التشغيل السريع كيفية الوصول إلى Table API لـ Azure Cosmos DB من تطبيق ‎.NET. Table API لـ Cosmos DB هي مخزن بيانات بلا مخطط يسمح للتطبيقات بتخزين بيانات NoSQL المنظمة في السحابة. لأنه يتم تخزين البيانات في تصميم بلا مخطط، يتم إضافة خصائص (أعمدة) جديدة تلقائياً إلى الجدول عند إضافة كائن بسمة جديدة إلى الجدول.

يمكن وصول تطبيقات ‎.NET إلى Table API لـ DB Cosmos باستخدام حزمة NuGet لـ Azure.Data.Tables. حزمة Azure.Data.Tables هي مكتبة ‎.NET Standard 2.0 تعمل مع تطبيقي ‎.NET Framework (الإصدار 4.7.2 والأحدث) و‎.NET Core (الإصدار 2.0 والأحدث).

المتطلبات الأساسية

يتم كتابة نموذج التطبيق في ‎.NET Core 3.1 على الرغم من أن المبادئ تنطبق على كل تطبيقي ‎.NET Framework و‎.NET Core. يمكنك استخدام Visual Studio أو Visual Studio لـ Mac أو تعليمة Visual Studio البرمجية كـ IDE.

في حال لم يكن لديك اشتراك في Azure، قم بإنشاءحساب مجاني قبل البدء.

تطبيق العينة

قد يتم استنساخ نموذج التطبيق لهذا البرنامج التعليمي أو تنزيله من المستودع https://github.com/Azure-Samples/msdocs-azure-data-tables-sdk-dotnet. يتم تضمين كل من تطبيق البداية والتطبيق المكتمل في مستودع النموذج.

git clone https://github.com/Azure-Samples/msdocs-azure-data-tables-sdk-dotnet

يستخدم نموذج التطبيق بيانات الطقس كمثال على إظهار إمكانيات واجهة برمجة تطبيقات الجدول. يتم تخزين الكائنات التي تمثل ملاحظات الطقس واستردادها باستخدام Table API، بما في ذلك تخزين الكائنات ذات الخصائص الإضافية لإظهار الإمكانيات بلا مخطط لـ Table API.

A screenshot of the finished application showing data stored in a Cosmos DB table using the Table API.

1 - إنشاء حساب على Azure Cosmos DB

تحتاج أولاً إلى إنشاء حساب على Cosmos DB Tables API سيحتوي على الجدول (الجداول) المستخدمة في التطبيق. يمكن إجراء ذلك باستخدام مدخل Microsoft Azure أو Azure CLI أو Azure PowerShell.

سجل الدخول إلى مدخل Microsoft Azure واتبع هذه الخطوات لإنشاء حساب على Cosmos DB.

الإرشادات لقطة شاشة
في مدخل Microsoft Azure:
  1. في شريط البحث أعلى مدخل Microsoft Azure، أدخل "cosmos db".
  2. في القائمة التي تظهر أسفل شريط البحث، ضمن Services، حدد العنصر المسمى Azure Cosmos DB.
A screenshot showing how to use the search box in the top tool bar to find Cosmos DB accounts in Azure.
في الصفحة ⁧⁩Azure Cosmos DB⁧⁩، حدد ⁧⁩إنشاء⁧⁩. A screenshot showing the Create button location on the Cosmos DB accounts page in Azure.
في الصفحة خيار تحديد واجهة برمجة التطبيقات، اختر الخيار جدول Azure. A screenshot showing the Azure Table option as the correct option to select.
على صفحة إنشاء حساب Azure Cosmos DB - جدول Azure، قم بتعبئة النموذج كما يلي.
  1. أنشئ مجموعة موارد جديدة لقاعدة بيانات Azure Cosmos المسماة rg-msdocs-tables-sdk-demo عن طريق تحديد الارتباط التشعبيإنشاء جديد ضمن مجموعة الموارد.
  2. امنح حساب قاعدة بيانات Azure Cosmos الخاص بك اسمًا cosmos-msdocs-tables-sdk-demo-XYZ حيث تمثل XYZ أي ثلاثة أحرف عشوائية لإنشاء اسم حساب فريد. يجب أن يتراوح طول أسماء حسابات Azure Cosmos DB من 3 إلى 44 حرفاً، وقد تحتوي على أحرف صغيرة أو أرقام أو واصلة (-) فقط.
  3. حدد المنطقة الخاصة بحساب قاعدة بيانات Azure Cosmos الخاص بك.
  4. حدد الأداء القياسي.
  5. حدد معدل النقل المزود لهذا المثال ضمن وضع السعة.
  6. حدد تطبيق ضمن تطبيق خصم مستوى مجاني لهذا المثال.
  7. حدد الزر مراجعة + إنشاء في أسفل الشاشة ثم حدد "إنشاء" على شاشة الملخص لإنشاء حساب Azure Cosmos DB. قد تستغرق هذه العملية عدة دقائق.
A screenshot showing how to fill out the fields on the Cosmos DB Account creation page.

2 - إنشاء جدول

بعد ذلك، تحتاج إلى إنشاء جدول في حسابك على Cosmos DB ليستخدمه تطبيقك. بعكس قاعدة بيانات تقليدية، تحتاج فقط إلى تحديد اسم الجدول، وليس الخصائص (الأعمدة) في الجدول. مع تحميل البيانات في الجدول، سيتم إنشاء الخصائص (الأعمدة) تلقائياً حسب الحاجة.

في مدخل Microsoft Azure، أكمل الخطوات التالية لإنشاء جدول في حسابك على Cosmos DB.

الإرشادات لقطة شاشة
في مدخل Microsoft Azure، انتقل إلى صفحة النظرة العامة لحساب Azure Cosmos DB. يمكنك الانتقال إلى صفحة النظرة العامة لحساب Cosmos DB الخاص بك عن طريق كتابة الاسم (cosmos-msdocs-table-sdk-demo-XYZ) لحساب Cosmos DB الخاص بك في شريط البحث العلوي والبحث أسفل عنوان الموارد. حساب Azure Cosmos DB الخاص بك للانتقال إلى صفحة النظرة العامة. A screenshot showing how to use the search box in the top tool bar to find your Cosmos DB account.
في صفحة النظرة العامة، حدد +إضافة جدول. سيتم تمرير مربع الحوار «جدول جديد» من الجانب الأيسر من الصفحة. A screenshot showing the location of the Add Table button.
في مربع الحوار New Table، بادر بتعبئة النموذج على النحو التالي.
  1. أدخِل اسم WeatherData لمُعرف الجدول. هذا هو اسم الجدول.
  2. حدد Manual ضمن Table throughput (autoscale) لهذا المثال.
  3. استخدم القيمة الافتراضية 400 ضمن وحدة الطلب/ ثانية المُقدرة خاصتك.
  4. حدد الزر OK لإنشاء الجدول.
A screenshot showing how to New Table dialog box for an Cosmos DB table.

3 - الحصول على سلسلة اتصال Cosmos DB

للوصول إلى الجدول (الجداول) في Cosmos DB، سيحتاج التطبيق إلى سلسلة اتصال الجدول لحساب CosmosDB Storage. يمكن استرداد سلسلة الاتصال باستخدام مدخل Microsoft Azure أو Azure CLI أو Azure PowerShell.

الإرشادات لقطة شاشة
على الجانب الأيمن من صفحة حساب Azure Cosmos DB، حدد موقع عنصر القائمة المسمى سلسلة الاتصال ضمن عنوان الإعدادات وحدده. سيتم نقلك إلى صفحة حيث يمكنك استرداد سلسلة الاتصال لحساب التخزين. A screenshot showing the location of the connection strings link on the Cosmos DB page.
انسخ قيمة سلسلة الاتصال الأساسية لاستخدامها في التطبيق الخاص بك. A screenshot showing the which connection string to select and use in your application.

تعد سلسلة الاتصال لحسابك على Cosmos DB بيانات سرية للتطبيق ويجب حمايتها مثل أي بيانات سرية أو كلمة مرور أخرى للتطبيق. يستخدم هذا المثال أداة Secret Manager لتخزين سلسلة الاتصال أثناء التطوير وجعلها متوفرة للتطبيق. يمكن الوصول إلى أداة Secret Manager من Visual Studio أو ‎.NET CLI.

لفتح أداة Secret Manager من Visual Studio، انقر بزر الماوس الأيمن فوق المشروع وحدد Manage User Secrets من قائمة السياق. سيؤدي ذلك إلى فتح ملف secrets.json للمشروع. استبدل محتويات الملف بـ JSON أدناه، مستبدلاً في سلسلة اتصال جدول Cosmos DB.

{
  "ConnectionStrings": {
    "CosmosTableApi": "<cosmos db table connection string>"
  }  
}

4 - تثبيت حزمة Azure.Data.Tables NuGet

للوصول إلى Table API لـ Cosmos DB من تطبيق ‎.NET، ثبِّت حزمة NuGet لـ Azure.Data.Tables.

Install-Package Azure.Data.Tables

5 - تكوين عميل Table في Startup.cs

تتصل Azure SDK بـ Azure باستخدام كائنات العميل لتنفيذ عمليات مختلفة على أساس Azure. يكون كائن TableClient هو الكائن المستخدم للاتصال بـ Table API لـ Cosmos DB.

سينشئ أحد التطبيقات عادة كائن TableClient واحداً لكل جدول لاستخدامه في التطبيق كله. من المستحسن استخدام حقن التبعيات (DI) وتسجيل كائن TableClient كقاعدة بيانات أحادية لإنجاز ذلك. لمزيد من المعلومات حول استخدام حقن التبعيات مع Azure SDK، راجع حقن التبعيات باستخدام Azure SDK لـ ‎.NET.

في ملف Startup.cs للتطبيق، حرر أسلوب ConfigureServices()‎ لمطابقة جزء التعليمات البرمجية التالي:

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages()
        .AddMvcOptions(options =>
        {
            options.Filters.Add(new ValidationFilter());
        });
    
    var connectionString = Configuration.GetConnectionString("CosmosTableApi");
    services.AddSingleton<TableClient>(new TableClient(connectionString, "WeatherData"));
    
    services.AddSingleton<TablesService>();
}

ستحتاج أيضاً إلى إضافة عبارة الاستخدام التالية في الجزء العلوي من ملف Startup.cs.

using Azure.Data.Tables;

6 - تنفيذ عمليات جدول Cosmos DB

يتم تنفيذ جميع عمليات جدول Cosmos DB لنموذج التطبيق بفئة TableService الموجودة في دليل Services. ستحتاج إلى استيراد مساحتي الاسم Azure وAzure.Data.Tables في الجزء العلوي من هذا الملف لاستخدام الكائنات في حزمة SDK لـ Azure.Data.Tables.

using Azure;
using Azure.Data.Tables;

في بداية فئة TableService، أضف متغير عضو لكائن TableClient ودالة إنشائية للسماح بحقن كائن TableClient في الفئة.

private TableClient _tableClient;

public TablesService(TableClient tableClient)
{
    _tableClient = tableClient;
}

الحصول على صفوف من جدول

تحتوي فئة TableClient على أسلوب يسمى Query الذي يسمح لك بتحديد صفوف من الجدول. في هذا المثال، نظراً لعدم تمرير أية معلمات إلى الأسلوب، سيتم تحديد جميع الصفوف من الجدول.

يأخذ الأسلوب أيضاً معلمة عامة من نوع ITableEntity تحدد أنه سيتم إرجاع بيانات فئة النموذج. في هذه الحالة، يتم استخدام الفئة المضمنة TableEntity، مما يعني أن أسلوب Query سيُرجِع مجموعة Pageable<TableEntity> كنتائج له.

public IEnumerable<WeatherDataModel> GetAllRows()
{
    Pageable<TableEntity> entities = _tableClient.Query<TableEntity>();

    return entities.Select(e => MapTableEntityToWeatherDataModel(e));
}

تحتوي فئة TableEntity المحددة في حزمة Azure.Data.Tables على خصائص لقيم مفتاح القسم ومفتاح الصف في الجدول. تكون هاتان القيمتان معاً لمفتاح فريد للصف في الجدول. في هذا المثال على التطبيق، يتم تخزين اسم محطة الطقس (المدينة) في مفتاح القسم، ويتم تخزين تاريخ/وقت الملاحظة في مفتاح الصف. يتم تخزين جميع الخصائص الأخرى (درجة الحرارة والرطوبة وسرعة الرياح) في قاموس في كائن TableEntity.

من الممارسات الشائعة تعيين كائن TableEntity إلى كائن من التعريف الخاص بك. يحدد نموذج التطبيق فئة WeatherDataModel في دليل Models لهذا الغرض. تحتوي هذه الفئة على خصائص اسم المحطة وتاريخ الملاحظة الذي سيتم تعيين مفتاح القسم ومفتاح الصف إليه، ما يوفر أسماء خصائص ذات معنى أكبر لهذه القيم. ثم تستخدم قاموساً لتخزين جميع الخصائص الأخرى في الكائن. هذا نمط شائع عند استخدام مخزن الجداول حيث يمكن أن يكون للصف أي عدد من الخصائص العشوائية ونريد أن تكون كائنات النموذج لدينا قادرة على تسجيل كل منها. تحتوي هذه الفئة أيضاً على أساليب لسرد الخصائص في الفئة.

public class WeatherDataModel 
{
    // Captures all of the weather data properties -- temp, humidity, wind speed, etc
    private Dictionary<string, object> _properties = new Dictionary<string, object>();

    public string StationName { get; set; }

    public string ObservationDate { get; set; }

    public DateTimeOffset? Timestamp { get; set; }

    public string Etag { get; set; }

    public object this[string name] 
    { 
        get => ( ContainsProperty(name)) ? _properties[name] : null; 
        set => _properties[name] = value; 
    }
    
    public ICollection<string> PropertyNames => _properties.Keys;

    public int PropertyCount => _properties.Count;

    public bool ContainsProperty(string name) => _properties.ContainsKey(name);       
}

يتم استخدام أسلوب MapTableEntityToWeatherDataModel لتعيين كائن TableEntity إلى كائن WeatherDataModel. يحتوي كائن TableEntity على خاصية Keys للحصول على جميع أسماء الخصائص الموجودة في الجدول للكائن (أسماء الأعمدة لهذا الصف في الجدول بشكلٍ فعال). يعين أسلوب MapTableEntityToWeatherDataModel خصائص PartitionKey وRowKey وTimestamp وEtag مباشرة، ثم يستخدم خاصية Keys للتكرار في الخصائص الأخرى في كائن TableEntity ويعين تلك الخصائص إلى كائن WeatherDataModel، مطروحاً منها الخصائص التي تم تعيينها مباشرة بالفعل.

حرر التعليمات البرمجية في أسلوب MapTableEntityToWeatherDataModel لمطابقة كتلة التعليمات البرمجية التالية.

public WeatherDataModel MapTableEntityToWeatherDataModel(TableEntity entity)
{
    WeatherDataModel observation = new WeatherDataModel();
    observation.StationName = entity.PartitionKey;
    observation.ObservationDate = entity.RowKey;
    observation.Timestamp = entity.Timestamp;
    observation.Etag = entity.ETag.ToString();

    var measurements = entity.Keys.Where(key => !EXCLUDE_TABLE_ENTITY_KEYS.Contains(key));
    foreach (var key in measurements)
    {
        observation[key] = entity[key];
    }
    return observation;            
}

تصفية الصفوف التي يتم إرجاعها من جدول

لتصفية الصفوف التي يتم إرجاعها من جدول، يمكنك تمرير سلسلة عامل تصفية نمط OData إلى أسلوب Query. على سبيل المثال، إذا أردت الحصول على جميع قراءات الطقس لمدينة شيكاغو بين منتصف ليل 1 يوليو 2021 ومنتصف ليل 2 يوليو 2021 (شاملة)، فستمر في سلسلة التصفية التالية.

PartitionKey eq 'Chicago' and RowKey ge '2021-07-01 12:00 AM' and RowKey le '2021-07-02 12:00 AM'

يمكنك عرض جميع عوامل تشغيل تصفية OData على موقع OData على الويب في قسم خيار استعلام نظام التصفية.

في مثال التطبيق، تم تصميم كائن FilterResultsInputModel لتسجيل أية معايير تصفية يوفرها المستخدم.

public class FilterResultsInputModel : IValidatableObject
{
    public string PartitionKey { get; set; }
    public string RowKeyDateStart { get; set; }
    public string RowKeyTimeStart { get; set; }
    public string RowKeyDateEnd { get; set; }
    public string RowKeyTimeEnd { get; set; }
    [Range(-100, +200)]
    public double? MinTemperature { get; set; }
    [Range(-100,200)]
    public double? MaxTemperature { get; set; }
    [Range(0, 300)]
    public double? MinPrecipitation { get; set; }
    [Range(0,300)]
    public double? MaxPrecipitation { get; set; }
}

عند تمرير هذا الكائن إلى أسلوب GetFilteredRows في فئة TableService، ينشئ سلسلة تصفية لكل قيمة خاصية غير خالية. ثم ينشئ سلسلة تصفية مجمعة عن طريق ربط جميع القيم مع عبارة "and". يتم تمرير سلسلة التصفية المجمعة هذه إلى أسلوب Query في كائن TableClient وسيتم إرجاع الصفوف المطابقة لسلسلة التصفية فقط. يمكنك استخدام أسلوب مشابه في التعليمات البرمجية لإنشاء سلاسل تصفية مناسبة كما هو مطلوب من تطبيقك.

public IEnumerable<WeatherDataModel> GetFilteredRows(FilterResultsInputModel inputModel)
{
    List<string> filters = new List<string>();

    if (!String.IsNullOrEmpty(inputModel.PartitionKey))
        filters.Add($"PartitionKey eq '{inputModel.PartitionKey}'");
    if (!String.IsNullOrEmpty(inputModel.RowKeyDateStart) && !String.IsNullOrEmpty(inputModel.RowKeyTimeStart))
        filters.Add($"RowKey ge '{inputModel.RowKeyDateStart} {inputModel.RowKeyTimeStart}'");
    if (!String.IsNullOrEmpty(inputModel.RowKeyDateEnd) && !String.IsNullOrEmpty(inputModel.RowKeyTimeEnd))
        filters.Add($"RowKey le '{inputModel.RowKeyDateEnd} {inputModel.RowKeyTimeEnd}'");
    if (inputModel.MinTemperature.HasValue)
        filters.Add($"Temperature ge {inputModel.MinTemperature.Value}");
    if (inputModel.MaxTemperature.HasValue)
        filters.Add($"Temperature le {inputModel.MaxTemperature.Value}");
    if (inputModel.MinPrecipitation.HasValue)
        filters.Add($"Precipitation ge {inputModel.MinTemperature.Value}");
    if (inputModel.MaxPrecipitation.HasValue)
        filters.Add($"Precipitation le {inputModel.MaxTemperature.Value}");

    string filter = String.Join(" and ", filters);
    Pageable<TableEntity> entities = _tableClient.Query<TableEntity>(filter);

    return entities.Select(e => MapTableEntityToWeatherDataModel(e));
}

إدراج بيانات باستخدام كائن TableEntity

أبسط طريقة لإضافة بيانات إلى جدول هي استخدام كائن TableEntity. في هذا المثال، يتم تعيين البيانات من كائن نموذج إدخال إلى كائن TableEntity. يتم تعيين الخصائص الموجودة في كائن الإدخال الذي يمثل اسم محطة الطقس وتاريخ/وقت الملاحظة إلى خاصيتي PartitionKey وRowKey على التوالي اللتين يشكلان معاً مفتاحاً فريداً للصف في الجدول. ثم يتم تعيين خصائص إضافية في كائن نموذج الإدخال إلى خصائص القاموس في كائن TableEntity. وأخيراً، يتم استخدام أسلوب AddEntity في كائن TableClient لإدراج البيانات في الجدول.

عدِّل فئة InsertTableEntity في مثال التطبيق لاحتواء التعليمات البرمجية التالية.

public void InsertTableEntity(WeatherInputModel model)
{
    TableEntity entity = new TableEntity();
    entity.PartitionKey = model.StationName;
    entity.RowKey = $"{model.ObservationDate} {model.ObservationTime}";

    // The other values are added like a items to a dictionary
    entity["Temperature"] = model.Temperature;
    entity["Humidity"] = model.Humidity;
    entity["Barometer"] = model.Barometer;
    entity["WindDirection"] = model.WindDirection;
    entity["WindSpeed"] = model.WindSpeed;
    entity["Precipitation"] = model.Precipitation;

    _tableClient.AddEntity(entity);
}

تحديث/إدراج البيانات باستخدام كائن TableEntity

إذا حاولت إدراج صف في جدول باستخدام تركيبة مفتاح قسم/مفتاح صف الموجودة بالفعل في هذا الجدول، فسيظهر لك خطأ. لهذا السبب، غالباً ما يفضل استخدام UpsertEntity بدلاً من أسلوب AddEntity عند إضافة صفوف إلى جدول. إذا كانت تركيبة مفتاح القسم /مفتاح الصف المحددة موجودة بالفعل في الجدول، فإن الأسلوب UpsertEntity سيحدِّث الصف الموجود. وإلا، فسيتم إضافة الصف إلى الجدول.

public void UpsertTableEntity(WeatherInputModel model)
{
    TableEntity entity = new TableEntity();
    entity.PartitionKey = model.StationName;
    entity.RowKey = $"{model.ObservationDate} {model.ObservationTime}";

    // The other values are added like a items to a dictionary
    entity["Temperature"] = model.Temperature;
    entity["Humidity"] = model.Humidity;
    entity["Barometer"] = model.Barometer;
    entity["WindDirection"] = model.WindDirection;
    entity["WindSpeed"] = model.WindSpeed;
    entity["Precipitation"] = model.Precipitation;

    _tableClient.UpsertEntity(entity);
}

إدراج بيانات ذات خصائص متغيرة أو تحديثها/إدراجها

إحدى مزايا استخدام Table API لـ Cosmos DB هي أنه إذا كان هناك كائن جارٍ تحميله إلى جدول ويحتوي على أية خصائص جديدة، فستتم إضافة هذه الخصائص تلقائياً إلى الجدول والقيم المخزنة في Cosmos DB. ليست هناك حاجة لتشغيل عبارات لغة تعريف البيانات (DDL)، مثل ALTER TABLE لإضافة أعمدة كما هو الحال في قاعدة البيانات التقليدية.

يمنح هذا النموذج المرونة للتطبيق عند التعامل مع مصادر البيانات التي قد تضيف أو تعدل البيانات التي تحتاج إلى تسجيلها بمرور الوقت أو عندما توفر مدخلات مختلفة بيانات مختلفة للتطبيق. في نموذج التطبيق، يمكننا محاكاة محطة الطقس التي ترسل ليس فقط بيانات الطقس الأساسية، ولكن أيضاً بعض القيم الإضافية. عند تخزين كائن بهذه الخصائص الجديدة في الجدول للمرة الأولى، ستتم إضافة الخصائص المطابقة (الأعمدة) تلقائياً إلى الجدول.

في نموذج التطبيق، يتم إنشاء فئة ExpandableWeatherObject حول قاموس داخلي لدعم أي مجموعة من الخصائص في الكائن. تمثل هذه الفئة نمطاً نموذجياً عندما يتعين احتواء كائن على مجموعة عشوائية من الخصائص.

public class ExpandableWeatherObject
{
    public Dictionary<string, object> _properties = new Dictionary<string, object>();

    public string StationName { get; set; }

    public string ObservationDate { get; set; }

    public object this[string name]
    {
        get => (ContainsProperty(name)) ? _properties[name] : null;
        set => _properties[name] = value;
    }

    public ICollection<string> PropertyNames => _properties.Keys;

    public int PropertyCount => _properties.Count;

    public bool ContainsProperty(string name) => _properties.ContainsKey(name);
}

لإدراج أو تحديث/إدراج هذا كائن باستخدام Table API، عيِّن خصائص الكائن القابل للتوسيع إلى كائن TableEntity واستخدم أسلوبي AddEntity أو UpsertEntity في كائن TableClient حسب الاقتضاء.

public void InsertExpandableData(ExpandableWeatherObject weatherObject)
{
    TableEntity entity = new TableEntity();
    entity.PartitionKey = weatherObject.StationName;
    entity.RowKey = weatherObject.ObservationDate;

    foreach (string propertyName in weatherObject.PropertyNames)
    {
        var value = weatherObject[propertyName];
        entity[propertyName] = value;
    }
    _tableClient.AddEntity(entity);
}

        
public void UpsertExpandableData(ExpandableWeatherObject weatherObject)
{
    TableEntity entity = new TableEntity();
    entity.PartitionKey = weatherObject.StationName;
    entity.RowKey = weatherObject.ObservationDate;

    foreach (string propertyName in weatherObject.PropertyNames)
    {
        var value = weatherObject[propertyName];
        entity[propertyName] = value;
    }
    _tableClient.UpsertEntity(entity);
}

تحديث كيان

يمكن تحديث الكيانات عن طريق استدعاء أسلوب UpdateEntity في كائن TableClient. نظراً لأن كياناً (صفاً) مخزناً باستخدام Table API قد يحتوي على أي مجموعة عشوائية من الخصائص، فإنه غالباً ما يكون من المفيد إنشاء كائن تحديث يستند حول كائن قاموس مشابهاً لـ ExpandableWeatherObject الذي ناقشناه سابقاً. في هذه الحالة، يكون الفرق الوحيد هو إضافة خاصية Etag التي يتم استخدامها للتحكم في التزامن أثناء التحديثات.

public class UpdateWeatherObject
{
    public Dictionary<string, object> _properties = new Dictionary<string, object>();

    public string StationName { get; set; }
    public string ObservationDate { get; set; }
    public string Etag { get; set; }

    public object this[string name]
    {
        get => (ContainsProperty(name)) ? _properties[name] : null;
        set => _properties[name] = value;
    }

    public ICollection<string> PropertyNames => _properties.Keys;

    public int PropertyCount => _properties.Count;

    public bool ContainsProperty(string name) => _properties.ContainsKey(name);
}

في نموذج التطبيق، يتم تمرير هذا الكائن إلى أسلوب UpdateEntity في فئة TableService. يعمل هذا الأسلوب أولاً على تحميل الكيان الموجود من Table API باستخدام أسلوب GetEntity في TableClient. ثم يعمل على تحديث كائن الكيان هذا ويستخدم أسلوب UpdateEntity حفظ التحديثات بقاعدة البيانات. لاحظ كيف يأخذ أسلوب UpdateEntity ‏Etag الحالية للكائن لضمان أن الكائن لم يتغير منذ تحميله في البداية. إذا كنت تريد تحديث الكيان بغض النظر عن ذلك، يمكنك تمرير قيمة ETag.All إلى أسلوب UpdateEntity.

public void UpdateEntity(UpdateWeatherObject weatherObject)
{
    string partitionKey = weatherObject.StationName;
    string rowKey = weatherObject.ObservationDate;

    // Use the partition key and row key to get the entity
    TableEntity entity = _tableClient.GetEntity<TableEntity>(partitionKey, rowKey).Value;

    foreach (string propertyName in weatherObject.PropertyNames)
    {
        var value = weatherObject[propertyName];
        entity[propertyName] = value;
    }

    _tableClient.UpdateEntity(entity, new ETag(weatherObject.Etag));
}

إزالة كيان

لإزالة كيان من جدول، استدعِ أسلوب DeleteEntity في كائن TableClient بمفتاح القسم ومفتاح الصف للكائن.

public void RemoveEntity(string partitionKey, string rowKey)
{
    _tableClient.DeleteEntity(partitionKey, rowKey);           
}

7 - تشغيل التعليمات البرمجية

شغِّل نموذج التطبيق للتفاعل مع Table API لـ Cosmos DB. في المرة الأولى التي تشغِّل فيها التطبيق، لن يكون هناك بيانات لأن الجدول فارغ. استخدم أياً من الأزرار الموجودة في الجزء العلوي من التطبيق لإضافة بيانات إلى الجدول.

A screenshot of the application showing the location of the buttons used to insert data into Cosmos DB using the Table A P I.

يؤدي تحديد الزر Insert using Table Entity إلى فتح مربع حوار يسمح لك بإدراج أو تحديث/إدراج صف جديد باستخدام كائن TableEntity.

A screenshot of the application showing the dialog box used to insert data using a TableEntity object.

يؤدي تحديد الزر Insert using Expandable Data إلى ظهور مربع حوار يمكِّنك من إدراج كائن ذي خصائص مخصصة، موضحاً كيفية عمل Table API لـ Cosmos DB تلقائياً على إضافة الخصائص (الأعمدة) إلى الجدول عند الحاجة. استخدم الزر Add Custom Field لإضافة خاصية جديدة واحدة أو أكثر وإظهار هذه الإمكانية.

A screenshot of the application showing the dialog box used to insert data using an object with custom fields.

استخدم الزر Insert Sample Data لتحميل نموذج بيانات في جدول Cosmos DB Table.

A screenshot of the application showing the location of the sample data insert button.

حدد عنصر Filter Results في القائمة العلوية ليتم نقله إلى صفحة "Filter Results". في هذه الصفحة، املأ معايير التصفية لتوضيح كيفية إنشاء عبارة تصفية وتمريرها إلى Table API لـ Cosmos DB.

A screenshot of the application showing filter results page and highlighting the menu item used to navigate to the page.

تنظيف الموارد

عند الانتهاء من نموذج التطبيق، يجب إزالة جميع موارد Azure المتعلقة بهذه المقالة من حسابك على Azure. يمكنك إجراء ذلك عن طريق حذف مجموعة الموارد.

يمكن حذف مجموعة موارد باستخدام مدخل Microsoft Azure عن طريق إجراء ما يلي.

الإرشادات لقطة شاشة
للانتقال إلى مجموعة الموارد، في شريط البحث، اكتب اسم مجموعة الموارد. ثم في علامة التبويب Resource Groups، حدد اسم مجموعة الموارد. A screenshot showing how to search for a resource group.
حدد Delete resource group من شريط الأدوات أعلى صفحة مجموعة الموارد. A screenshot showing the location of the Delete resource group button.
سيظهر مربع حوار من يمين الشاشة يطلب منك تأكيد حذف مجموعة الموارد.
  1. اكتب الاسم الكامل لمجموعة الموارد في مربع النص لتأكيد الحذف على النحو المحدد.
  2. اضغط الزر Delete أسفل الصفحة.
A screenshot showing the confirmation dialog for deleting a resource group.

الخطوات التالية

في هذه البداية السريعة، تعلمت كيفية إنشاء حساب Azure Cosmos DB، وإنشاء جدول باستخدام مستكشف البيانات، وتشغيل تطبيق. الآن يمكنك الاستعلام عن البيانات الخاصة بك باستخدام API الجدول.