تمرين - إضافة EF Core إلى الحد الأدنى من واجهة برمجة التطبيقات
أنت مطور لشركة، وقد سمعت أنت وشركتك عن الحد الأدنى الجديد من واجهة برمجة التطبيقات. طلب منك مديرك إنشاء مشروع له بحيث يمكنك مناقشة ما إذا كنت تريد استخدامه في مشروعك التالي.
ملاحظه
تستخدم هذه الوحدة النمطية .NET CLI (واجهة سطر الأوامر) وVisual Studio Code للتطوير المحلي. بعد إكمال هذه الوحدة النمطية، يمكنك تطبيق المفاهيم باستخدام Visual Studio (Windows) أو Visual Studio for Mac (macOS) أو التطوير المستمر باستخدام Visual Studio Code (Windows وLinux & macOS).
تستخدم هذه الوحدة النمطية .NET 8.0 SDK. تأكد من تثبيت .NET 8.0 عن طريق تشغيل الأمر التالي في الوحدة الطرفية للأوامر المفضلة لديك:
dotnet --list-sdks
يظهر إخراج مشابه للمثال التالي:
6.0.317 [C:\Program Files\dotnet\sdk]
7.0.401 [C:\Program Files\dotnet\sdk]
8.0.100 [C:\Program Files\dotnet\sdk]
تأكد من إدراج إصدار يبدأ 8. إذا لم يتم سرد أي شيء أو لم يتم العثور على الأمر، تثبيت أحدث .NET 8.0 SDK.
إعداد المشروع
أولا، تحتاج إلى إنشاء مشروع. لقد قمت بتثبيت .NET 6 وأنت جاهز للبدء. في هذه الوحدة، ستضيف استمرار البيانات إلى واجهة برمجة تطبيقات إدارة البيتزا.
في المحطة الطرفية، قم بإنشاء واجهة برمجة تطبيقات ويب عن طريق تشغيل
dotnet new:dotnet new web -o PizzaStore -f net8.0يجب أن تشاهد دليل PizzaStore.
انتقل إلى دليل PizzaStore عن طريق إدخال الأمر التالي:
cd PizzaStoreتثبيت حزمة Swashbuckle:
dotnet add package Swashbuckle.AspNetCore --version 6.5.0افتح المشروع في Visual Studio Code.
باستخدام Visual Studio Code، قم بإنشاء ملف Pizza.cs في جذر المشروع وأعطه المحتوى التالي:
namespace PizzaStore.Models { public class Pizza { public int Id { get; set; } public string? Name { get; set; } public string? Description { get; set; } } }فئة
Pizzaالسابقة هي عنصر بسيط يمثل البيتزا. هذه التعليمة البرمجية هي نموذج البيانات الخاص بك. لاحقا، ستستخدم Entity Framework (EF) Core لتعيين نموذج البيانات هذا إلى جدول قاعدة بيانات.افتح Program.cs وأضف التعليمات البرمجية المميزة:
using Microsoft.OpenApi.Models; var builder = WebApplication.CreateBuilder(args); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "PizzaStore API", Description = "Making the Pizzas you love", Version = "v1" }); }); var app = builder.Build(); if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "PizzaStore API V1"); }); } app.MapGet("/", () => "Hello World!"); app.Run();قد تتلقى مطالبة من Visual Studio Code لإضافة أصول لتصحيح أخطاء المشروع. حدد
Yesفي مربع الحوار.
إضافة EF Core إلى المشروع
لتخزين العناصر في قائمة to-do، قم بتثبيت حزمة EntityFrameworkCore.InMemory.
اضغط على Ctrl+' لفتح محطة طرفية في Visual Studio Code. في المحطة الطرفية الجديدة، أدخل التعليمات البرمجية التالية لإضافة حزمة EF Core InMemory:
dotnet add package Microsoft.EntityFrameworkCore.InMemory --version 8.0أضف
using Microsoft.EntityFrameworkCore;إلى أعلى ملفات Program.cs وملفات Pizza.cs.الآن بعد أن تمت إضافة EF Core إلى المشروع، يمكنك توصيل التعليمات البرمجية الخاصة بك بالبيانات التي تريد حفظها والاستعلام عنها. للقيام بهذه الخطوة، يمكنك إنشاء فئة
PizzaDb. ستقوم فئةPizzaDbبالمهام التالية:- كشف خاصية
Pizzasمن قائمةPizzaفي قاعدة البيانات. - استخدم
UseInMemoryDatabaseلربط تخزين قاعدة البيانات في الذاكرة. يتم تخزين بياناتك هنا طالما أن التطبيق قيد التشغيل.
- كشف خاصية
لإعداد قاعدة البيانات في الذاكرة، أضف التعليمات البرمجية التالية إلى أسفل ملف Pizza.cs (أعلى
}النهائي ). سيكون لديك تعريفان للفئة داخل مساحة الاسمPizzaStore.Models.class PizzaDb : DbContext { public PizzaDb(DbContextOptions options) : base(options) { } public DbSet<Pizza> Pizzas { get; set; } = null!; }يمثل
DbContextاتصالا أو جلسة عمل تستخدم للاستعلام عن مثيلات الكيانات وحفظها في قاعدة بيانات.أضف
using PizzaStore.Models;إلى أعلى ملف Program.cs.في Program.cs، قبل استدعاء
AddSwaggerGen، أضف التعليمات البرمجية التالية:builder.Services.AddDbContext<PizzaDb>(options => options.UseInMemoryDatabase("items"));
إرجاع قائمة بالعناصر
للقراءة من قائمة العناصر في قائمة البيتزا، أضف التعليمات البرمجية التالية أعلى الاستدعاء إلى
app.Run();لإضافة مسار "/pizzas":app.MapGet("/pizzas", async (PizzaDb db) => await db.Pizzas.ToListAsync());
تشغيل التطبيق
تأكد من حفظ جميع التغييرات. قم بتشغيل التطبيق عن طريق استدعاء
dotnet runفي المحطة الطرفية. سيؤدي هذا الإجراء إلى إنشاء التطبيق واستضافته على منفذ من 5000-5300. سيكون ل HTTPS منفذ محدد له في النطاق 7000-7300.ملاحظه
إذا كنت تريد تجاوز سلوك تحديد المنفذ العشوائي، يمكنك تعيين المنافذ لاستخدامها في launchSettings.json.
dotnet runإليك ما يمكن أن يبدو عليه الإخراج في المحطة الطرفية:
Building... info: Microsoft.Hosting.Lifetime[14] Now listening on: https://localhost:7200 info: Microsoft.Hosting.Lifetime[14] Now listening on: http://localhost:5100 info: Microsoft.Hosting.Lifetime[0] Application started. Press Ctrl+C to shut down. info: Microsoft.Hosting.Lifetime[0] Hosting environment: Development info: Microsoft.Hosting.Lifetime[0] Content root path: /<path>/PizzaStoreفي المستعرض، انتقل إلى https://localhost:{PORT}/swagger. حدد زر
GET /pizzas، متبوعا جربهExecute. سترى أن القائمة فارغة ضمنResponse body.في المحطة الطرفية، اضغط على Ctrl+C لإيقاف تشغيل البرنامج.
إنشاء عناصر جديدة
دعونا نضيف التعليمات البرمجية إلى POST عناصر جديدة إلى قائمة البيتزا. في Program.cs، أضف التعليمات البرمجية التالية ضمن app.MapGet التي قمت بإنشائها سابقا.
app.MapPost("/pizza", async (PizzaDb db, Pizza pizza) =>
{
await db.Pizzas.AddAsync(pizza);
await db.SaveChangesAsync();
return Results.Created($"/pizza/{pizza.Id}", pizza);
});
اختبار واجهة برمجة التطبيقات
تأكد من حفظ جميع التغييرات وتشغيل التطبيق مرة أخرى. ارجع إلى واجهة مستخدم Swagger والآن يجب أن ترى POST/pizza. لإضافة عناصر جديدة إلى قائمة البيتزا:
حدد POST /pizza.
حدد جربه.
استبدل نص الطلب ب JSON التالي:
{ "name": "Pepperoni", "description": "A classic pepperoni pizza" }حدد Execute.
لقراءة العناصر في القائمة:
حدد GET /pizzas.
حدد جربه.
حدد Execute.
سيتضمن
Response bodyالعناصر المضافة للتو.[ { "id": 1, "name": "Pepperoni", "description": "A classic pepperoni pizza" } ]اضغط على Ctrl+C في المحطة الطرفية لإيقاف تشغيل التطبيق. بالنسبة لبقية هذا التمرين، قم بإيقاف التطبيق وإعادة تشغيله كما هو مطلوب لاختبار التغييرات التي أجريتها. تأكد من حفظ جميع التغييرات قبل
dotnet run!
الحصول على عنصر واحد
للحصول على عنصر حسب id، أضف التعليمات البرمجية ضمن مسار app.MapPost الذي أنشأته سابقا.
app.MapGet("/pizza/{id}", async (PizzaDb db, int id) => await db.Pizzas.FindAsync(id));
اختبار GET حسب المعرف
لاختبار هذه العملية، يمكنك إما الانتقال إلى https://localhost:{PORT}/pizza/1 أو استخدام واجهة مستخدم Swagger. نظرا لأنك تستخدم قاعدة بيانات في الذاكرة، فلن يتم سرد البيتزا التي أنشأتها مسبقا إذا قمت بإعادة تشغيل التطبيق. لذلك، ستحتاج إلى استخدام عملية POST لإضافتها مرة أخرى.
تحديث عنصر
لتحديث عنصر موجود، أضف التعليمات البرمجية ضمن المسار GET /pizza/{id} الذي أنشأته:
app.MapPut("/pizza/{id}", async (PizzaDb db, Pizza updatepizza, int id) =>
{
var pizza = await db.Pizzas.FindAsync(id);
if (pizza is null) return Results.NotFound();
pizza.Name = updatepizza.Name;
pizza.Description = updatepizza.Description;
await db.SaveChangesAsync();
return Results.NoContent();
});
اختبار PUT
حدد PUT /pizza/{id} في واجهة مستخدم Swagger.
حدد جربه.
في مربع النص معرف، أدخل 1.
وأخيرا، قم بتحديث
Request body. الصق JSON التالي وقم بتغييرnameإلىPineapple.{ "id": 1, "name": "Pineapple" }حدد Execute.
لاختبار التعليمات البرمجية، قم بالتمرير مرة أخرى إلى GET /pizza/{id}. البيتزا الآن لها الاسم Pineapple.
حذف عنصر
لحذف عنصر موجود، أضف التعليمات البرمجية ضمن PUT /pizza/{id} التي قمت بإنشائها سابقا:
app.MapDelete("/pizza/{id}", async (PizzaDb db, int id) =>
{
var pizza = await db.Pizzas.FindAsync(id);
if (pizza is null)
{
return Results.NotFound();
}
db.Pizzas.Remove(pizza);
await db.SaveChangesAsync();
return Results.Ok();
});
اختبار الحذف
حاول الآن حذف عنصر باستخدام واجهة Swagger.
في هذه الوحدة، أضفت EF Core إلى تطبيق واجهة برمجة تطبيقات الحد الأدنى الموجود واستخدمت قاعدة بيانات في الذاكرة لتخزين البيانات. بعد ذلك، ستتعلم كيفية استخدام قاعدة بيانات حقيقية لتخزين البيانات بحيث تستمر بين إيقاف تشغيل التطبيق.