Fluent API va annotatsiya Reja: 1. Fluent API ga kirish. 2. Fluent API usullari. 3. Fluent API da xaritalash. Fluent API - bu model konfiguratsiyasini belgilashning ilg'or usuli bo'lib, u ma'lumotlar izohlari bilan bo'lishi mumkin bo'lmagan ba'zi rivojlangan konfiguratsiyalarga qo'shimcha ravishda ma'lumotlar izohlari qila oladigan hamma narsani qamrab oladi. Ma'lumotlar izohlari va ravon API birgalikda ishlatilishi mumkin, lekin Code First Fluent API > ma'lumotlar izohlari > standart konventsiyalariga ustunlik beradi. Fluent API - domen sinflarini sozlashning yana bir usuli. Code First Fluent API-ga odatda olingan DbContext-da OnModelCreating usulini bekor qilish orqali kirish mumkin. Fluent API konfiguratsiya uchun DataAnnotations-ga qaraganda ko'proq funksionallikni ta'minlaydi. Fluent API quyidagi turdagi xaritalarni qo‘llabquvvatlaydi. Ushbu bobda biz quyidagi kodda ko'rsatilganidek, Talaba, Kurs va Ro'yxatdan o'tish sinflari va MyContext nomi bilan bitta kontekst sinfini o'z ichiga olgan oddiy misol bilan davom etamiz. using System.Data.Entity; using System.Linq; using System.Text; using System.Threading.Tasks; namespace EFCodeFirstDemo { class Program { static void Main(string[] args) {} } public enum Grade { A, B, C, D, F } public class Enrollment { public int EnrollmentID { get; set; } public int CourseID { get; set; } public int StudentID { get; set; } public Grade? Grade { get; set; } public virtual Course Course { get; set; } public virtual Student Student { get; set; } } public class Student { public int ID { get; set; } public string LastName { get; set; } public string FirstMidName { get; set; } public DateTime EnrollmentDate { get; set; } public virtual ICollection<Enrollment> Enrollments { get; set; } } public class Course { public int CourseID { get; set; } public string Title { get; set; } public int Credits { get; set; } public virtual ICollection<Enrollment> Enrollments { get; set; } } public class MyContext : DbContext { public virtual DbSet<Course> Courses { get; set; } public virtual DbSet<Enrollment> Enrollments { get; set; } public virtual DbSet<Student> Students { get; set; } } } Fluent API-ga kirish uchun DbContext-dagi OnModelCreating usulini bekor qilish kerak. Keling, oddiy misolni ko'rib chiqaylik, unda biz talabalar jadvalidagi ustun nomini quyidagi kodda ko'rsatilganidek FirstMidName dan FirstName ga o'zgartiramiz. public class MyContext : DbContext { protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<Student>().Property(s ⇒ s.FirstMidName) .HasColumnName("FirstName");} public virtual DbSet<Course> Courses { get; set; } public virtual DbSet<Enrollment> Enrollments { get; set; } public virtual DbSet<Student> Students { get; set; } } DbModelBuilder CLR sinflarini ma'lumotlar bazasi sxemasiga solishtirish uchun ishlatiladi. Bu asosiy sinf bo'lib, unda siz barcha domen sinflaringizni sozlashingiz mumkin. Ob'ekt ma'lumotlari modelini (EDM) yaratish uchun ushbu kodga asoslangan yondashuv Code First sifatida tanilgan. Fluent API turli xil Code First konventsiyalarini bekor qilish uchun ob'ektlar va uning xususiyatlarini sozlash uchun bir qator muhim usullarni taqdim etadi. Quyida ulardan ba'zilari keltirilgan. T/R Usul nomi va tavsifi 1 ComplexType<TComplexType> Turni modeldagi murakkab tur sifatida qayd qiladi va murakkab turni sozlash uchun ishlatilishi mumkin bo'lgan ob'ektni qaytaradi. Ushbu usul bir nechta konfiguratsiya qatorini bajarish uchun bir xil turdagi uchun bir necha marta chaqirilishi mumkin. 2 Entity<TEntityType> Modelning bir qismi sifatida ob'ekt turini ro'yxatdan o'tkazadi va ob'ektni sozlash uchun ishlatilishi mumkin bo'lgan ob'ektni qaytaradi. Ushbu usul bir xil ob'ekt uchun bir nechta konfiguratsiya qatorini bajarish uchun bir necha marta chaqirilishi mumkin. 3 HasKey<TKey> Ushbu ob'ekt turi uchun asosiy kalit xususiyati(lar)ni sozlaydi. 4 HasMany<TTargetEntity> Ushbu ob'ekt turidagi ko'plab munosabatlarni sozlaydi. 5 HasOptional<TTargetEntity> Ushbu ob'ekt turidan ixtiyoriy munosabatni sozlaydi. Ob'ekt turidagi misollar ma'lumotlar bazasiga ushbu munosabat ko'rsatilmagan holda saqlanishi mumkin. Ma'lumotlar bazasidagi xorijiy kalit null bo'ladi. 6 HasRequired<TTargetEntity> Ushbu ob'ekt turidan kerakli munosabatni sozlaydi. Ob'ekt tipidagi misollar, agar bu munosabat belgilanmaguncha, ma'lumotlar bazasiga saqlanmaydi. Ma'lumotlar bazasidagi chet el kaliti null bo'lmaydi. 7 Ignore<TProperty> Xususiyatni modeldan chiqarib tashlaydi, shuning uchun u ma'lumotlar bazasiga ko'rsatilmaydi. (StructuralTypeConfiguration<TStructuralType> dan meros qilib olingan) 8 Property<T> Ushbu turda aniqlangan struktura xususiyatini sozlaydi. (StructuralTypeConfiguration<TStructuralType> dan meros qilib olingan) 9 ToTable(String) Ushbu ob'ekt turiga mos keladigan jadval nomini sozlaydi. Fluent API sizga ob'ektlaringiz yoki ularning xususiyatlarini sozlash imkonini beradi, ular ma'lumotlar bazasiga qanday joylashishi yoki bir-biriga qanday aloqasi borligini o'zgartirishni xohlaysizmi. Konfiguratsiyalardan foydalanishga ta'sir ko'rsatishingiz mumkin bo'lgan juda ko'p turli xil xaritalash va modellashtirish mavjud. Quyida Fluent API qo'llab-quvvatlaydigan xaritalashning asosiy turlari keltirilgan: Ob'ektni xaritalash Xususiyatlarni xaritalash Ob'ektni xaritalash Ob'ektni xaritalash - bu oddiy xaritalashlar bo'lib, ular Entity Framework-ning sinflar ma'lumotlar bazalari bilan qanday ko'rsatilganligini tushunishiga ta'sir qiladi. Bularning barchasini biz ma'lumotlar izohlarida muhokama qildik va bu yerda Fluent API yordamida xuddi shunday narsalarga qanday erishish mumkinligini ko'rib chiqamiz. Shunday qilib, ushbu konfiguratsiyalarni qo'shish uchun domen sinflariga kirishdan ko'ra, biz buni kontekstda qilishimiz mumkin. Birinchi narsa, modelBuilder-ga ishlash imkonini beradigan OnModelCreating usulini bekor qilishdir. Standart sxema Ma'lumotlar bazasi yaratilganda standart sxema dbo hisoblanadi. Barcha jadvallar, saqlangan protseduralar va hokazolar uchun ishlatiladigan ma'lumotlar bazasi sxemasini belgilash uchun DbModelBuilder-da HasDefaultSchema usulidan foydalanish mumkin. Keling, administrator sxemasi qo'llaniladigan quyidagi misolni ko'rib chiqaylik. public class MyContext : DbContext { public MyContext() : base("name = MyContextDB") {} protected override void OnModelCreating(DbModelBuilder modelBuilder) { //Configure default schema modelBuilder.HasDefaultSchema("Admin"); } public virtual DbSet<Course> Courses { get; set; } public virtual DbSet<Enrollment> Enrollments { get; set; } public virtual DbSet<Student> Students { get; set; } } Ob'ektni jadvalga xaritasi Standart konventsiya bilan Code First kurslar, ro'yxatga olishlar va talabalar kabi kontekst sinfida DbSet xususiyatlari nomi bilan ma'lumotlar bazasi jadvallarini yaratadi. Ammo agar siz turli xil jadval nomlarini xohlasangiz, ushbu konventsiyani bekor qilishingiz va quyidagi kodda ko'rsatilganidek, DbSet xususiyatlaridan boshqa jadval nomini berishingiz mumkin. protected override void OnModelCreating(DbModelBuilder modelBuilder) { //Configure default schema modelBuilder.HasDefaultSchema("Admin"); //Map entity to table modelBuilder.Entity<Student>().ToTable("StudentData"); modelBuilder.Entity<Course>().ToTable("CourseDetail"); modelBuilder.Entity<Enrollment>().ToTable("EnrollmentInfo"); } Ma'lumotlar bazasi yaratilganda, OnModelCreating usulida ko'rsatilgan jadvallar nomini ko'rasiz. Ob'ektni bo'lish (ob'ektni bir nechta jadvalga xaritalash) Entity Splitting sizga bir nechta jadvallardan keladigan ma'lumotlarni bitta sinfga birlashtirish imkonini beradi va u faqat ular o'rtasida birma-bir munosabatga ega bo'lgan jadvallar bilan ishlatilishi mumkin. Keling, quyidagi misolni ko'rib chiqaylik, unda Talabalar haqidagi ma'lumotlar ikkita jadvalga joylashtirilgan. protected override void OnModelCreating(DbModelBuilder modelBuilder) { //Configure default schema modelBuilder.HasDefaultSchema("Admin"); //Map entity to table modelBuilder.Entity<Student>().Map(sd ⇒ { sd.Properties(p ⇒ new { p.ID, p.FirstMidName, p.LastName }); sd.ToTable("StudentData"); }) .Map(si ⇒ { si.Properties(p ⇒ new { p.ID, p.EnrollmentDate }); si.ToTable("StudentEnrollmentInfo"); }); modelBuilder.Entity<Course>().ToTable("CourseDetail"); modelBuilder.Entity<Enrollment>().ToTable("EnrollmentInfo"); } Yuqoridagi kodda Xarita usulidan foydalanib, ba'zi xususiyatlarni StudentData jadvaliga va ba'zi xususiyatlarni StudentEnrollmentInfo jadvaliga solishtirish orqali Talaba ob'ekti quyidagi ikkita jadvalga bo'linganligini ko'rishingiz mumkin. StudentData - Talabaning ismi va familiyasini o'z ichiga oladi. StudentEnrollmentInfo - Ro'yxatdan o'tish sanasini o'z ichiga oladi. Ma'lumotlar bazasi yaratilganda siz quyidagi rasmda ko'rsatilganidek, ma'lumotlar bazasida quyidagi jadvallarni ko'rasiz. Xususiyatlarni xaritalash Property usuli ob'ekt yoki murakkab turga tegishli bo'lgan har bir xususiyat uchun atributlarni sozlash uchun ishlatiladi. Property usuli berilgan xususiyat uchun konfiguratsiya ob'ektini olish uchun ishlatiladi. Shuningdek, Fluent API yordamida domen sinflaringiz xususiyatlarini xaritalash va sozlashingiz mumkin. Birlamchi kalitni sozlash Asosiy kalitlar uchun standart konventsiya Sinf nomi "ID" yoki "Id" bo'lgan xususiyatni belgilaydi Sinf nomidan keyin “ID” yoki “Id” Agar sinfingiz quyidagi Student klassi kodida ko'rsatilganidek, asosiy kalit uchun standart konventsiyalarga rioya qilmasa public class Student { public int StdntID { get; set; } public string LastName { get; set; } public string FirstMidName { get; set; } public DateTime EnrollmentDate { get; set; } public virtual ICollection<Enrollment> Enrollments { get; set; } } Keyin xususiyatni asosiy kalit sifatida aniq belgilash uchun quyidagi kodda ko'rsatilganidek, HasKey usulidan foydalanishingiz mumkin protected override void OnModelCreating(DbModelBuilder modelBuilder) { //Configure default schema modelBuilder.HasDefaultSchema("Admin"); // Configure Primary Key modelBuilder.Entity<Student>().HasKey<int>(s ⇒ s.StdntID); } Ustunni sozlash Entity Framework'da sukut bo'yicha Code First bir xil nom, tartib va ma'lumotlar turiga ega xususiyat uchun ustun yaratadi. Ammo siz quyidagi kodda ko'rsatilganidek, ushbu konventsiyani bekor qilishingiz mumkin. protected override void OnModelCreating(DbModelBuilder modelBuilder) { //Configure default schema modelBuilder.HasDefaultSchema("Admin"); //Configure EnrollmentDate Column modelBuilder.Entity<Student>().Property(p ⇒ p.EnrollmentDate) .HasColumnName("EnDate") .HasColumnType("DateTime") .HasColumnOrder(2); } MaxLength xususiyatini sozlang Quyidagi misolda Kurs sarlavhasi xususiyati 24 belgidan oshmasligi kerak. Agar foydalanuvchi 24 belgidan uzunroq qiymatni belgilasa, foydalanuvchi DbEntityValidationException istisnosini oladi. protected override void OnModelCreating(DbModelBuilder modelBuilder) { //Configure default schema modelBuilder.HasDefaultSchema("Admin"); modelBuilder.Entity<Course>().Property(p ⇒ p.Title).HasMaxLength(24); } Null yoki NotNull xususiyatini sozlang Quyidagi misolda Kurs sarlavhasi xususiyati talab qilinadi, shuning uchun IsRequired usuli NotNull ustunini yaratish uchun ishlatiladi. Xuddi shunday, Student EnrollmentDate ixtiyoriy, shuning uchun biz quyidagi kodda ko'rsatilganidek, ushbu ustunda null qiymatga ruxsat berish uchun IsOptional usulidan foydalanamiz. protected override void OnModelCreating(DbModelBuilder modelBuilder) { //Configure default schema modelBuilder.HasDefaultSchema("Admin"); modelBuilder.Entity<Course>().Property(p ⇒ p.Title).IsRequired(); modelBuilder.Entity<Student>().Property(p ⇒ p.EnrollmentDate).IsOptional(); //modelBuilder.Entity<Student>().Property(s ⇒ s.FirstMidName) //.HasColumnName("FirstName"); } Aloqalarni sozlash Ma'lumotlar bazalari kontekstidagi munosabatlar - bu ikkita relyatsion ma'lumotlar bazasi jadvallari o'rtasida mavjud bo'lgan vaziyat, agar bitta jadval boshqa jadvalning asosiy kalitiga havola qiladigan tashqi kalitga ega bo'lsa. Code First bilan ishlashda siz domeningizning CLR sinflarini belgilash orqali modelingizni aniqlaysiz. Odatiy bo'lib, Entity Framework sizning sinflaringizni ma'lumotlar bazasi sxemasiga solishtirish uchun Code First konventsiyalaridan foydalanadi. Agar siz Code First nomlash konventsiyalaridan foydalansangiz, ko'p hollarda tashqi kalitlar va navigatsiya xususiyatlariga asoslangan jadvallaringiz o'rtasidagi munosabatlarni o'rnatish uchun Code First-ga tayanishingiz mumkin. Agar ular ushbu konventsiyalarga mos kelmasa, siz Code First-ga konfiguratsiyalarni qo'shayotganingizda sinflar o'rtasidagi munosabatlarga va bu munosabatlar ma'lumotlar bazasida qanday amalga oshirilishiga ta'sir qilish uchun foydalanishingiz mumkin bo'lgan konfiguratsiyalar ham mavjud. Ulardan ba'zilari ma'lumotlar izohlarida mavjud va siz Fluent API bilan yanada murakkabroqlarini qo'llashingiz mumkin. Birga-bir munosabatlarni sozlang Modelingizda birma-bir munosabatni aniqlaganingizda, har bir sinfda mos yozuvlar navigatsiya xususiyatidan foydalanasiz. Ma'lumotlar bazasida ikkala jadval munosabatlarning har ikki tomonida faqat bitta yozuvga ega bo'lishi mumkin. Har bir asosiy kalit qiymati tegishli jadvaldagi faqat bitta yozuvga (yoki hech qanday yozuvga) tegishli. Yakkama-yakka munosabat, agar tegishli ustunlarning ikkalasi ham asosiy kalit bo'lsa yoki noyob cheklovlarga ega bo'lsa, yaratiladi. Yakkama-yakka munosabatda asosiy kalit qo'shimcha ravishda tashqi kalit vazifasini bajaradi va ikkala jadval uchun alohida tashqi kalit ustuni mavjud emas. Ushbu turdagi munosabatlar keng tarqalgan emas, chunki bu tarzda bog'liq bo'lgan ko'pchilik ma'lumotlar bitta jadvalda bo'ladi. Keling, quyidagi misolni ko'rib chiqaylik, u erda biz bir-bir munosabatlarni yaratish uchun modelimizga boshqa sinf qo'shamiz. public class Student { public int ID { get; set; } public string LastName { get; set; } public string FirstMidName { get; set; } public DateTime EnrollmentDate { get; set; } public virtual StudentLogIn StudentLogIn { get; set; } public virtual ICollection<Enrollment> Enrollments { get; set; } } public class StudentLogIn { [Key, ForeignKey("Student")] public int ID { get; set; } public string EmailID { get; set; } public string Password { get; set; } public virtual Student Student { get; set; } } Yuqoridagi kodda ko'rib turganingizdek, Key va ForeignKey atributlari StudentLogIn sinfidagi ID xususiyati uchun uni asosiy kalit va tashqi kalit sifatida belgilash uchun ishlatiladi. Fluent API yordamida Student va StudentLogIn oʻrtasida birdan nolga yoki bitta munosabatni sozlash uchun quyidagi kodda koʻrsatilganidek, OnModelCreating usulini bekor qilishingiz kerak. protected override void OnModelCreating(DbModelBuilder modelBuilder) { //Configure default schema modelBuilder.HasDefaultSchema("Admin"); // Configure ID as PK for StudentLogIn modelBuilder.Entity<StudentLogIn>() .HasKey(s ⇒ s.ID); // Configure ID as FK for StudentLogIn modelBuilder.Entity<Student>() .HasOptional(s ⇒ s.StudentLogIn) //StudentLogIn is optional .WithRequired(t ⇒ t.Student); // Create inverse relationship } Ko'pgina hollarda, Entity Framework munosabatlarda qaysi turga bog'liq va qaysi biri asosiy ekanligini aniqlashi mumkin. Biroq, munosabatlarning ikkala uchi ham zarur bo'lsa yoki ikkala tomon ham ixtiyoriy bo'lsa, Entity Framework qaram va asosiyni aniqlay olmaydi. Aloqaning ikkala uchi ham talab qilinganda, quyidagi kodda ko'rsatilganidek, HasRequired dan foydalanishingiz mumkin. protected override void OnModelCreating(DbModelBuilder modelBuilder) { //Configure default schema modelBuilder.HasDefaultSchema("Admin"); // Configure ID as PK for StudentLogIn modelBuilder.Entity<StudentLogIn>() .HasKey(s ⇒ s.ID); // Configure ID as FK for StudentLogIn modelBuilder.Entity<Student>() .HasRequired(r ⇒ r.Student) .WithOptional(s ⇒ s.StudentLogIn); } Ma'lumotlar bazasi yaratilganda, quyidagi rasmda ko'rsatilganidek, munosabatlar yaratilganligini ko'rasiz. Birlamchi kalit jadvali tegishli jadvaldagi hech, bitta yoki ko'p yozuvlarga tegishli bo'lgan faqat bitta yozuvni o'z ichiga oladi. Bu munosabatlarning eng ko'p qo'llaniladigan turi. Ushbu turdagi munosabatlarda A jadvalidagi satr B jadvalidagi ko'p mos keladigan qatorlarga ega bo'lishi mumkin, ammo B jadvalidagi satr A jadvalidagi faqat bitta mos keladigan qatorga ega bo'lishi mumkin. Chet el kaliti munosabatlarning ko'p sonini ifodalovchi jadvalda aniqlanadi. Misol uchun, yuqoridagi diagrammada Talaba va Ro'yxatga olish jadvallari birtoman munosabatiga ega, har bir talaba ko'p ro'yxatga olishlari mumkin, lekin har bir ro'yxatga olish faqat bitta talabaga tegishli. Quyida “Talaba” va “Ro‘yxatdan o‘tish” bir-biriga bog‘langan, ammo Ro‘yxatga olish jadvalidagi xorijiy kalit standart Code First qoidalariga amal qilmaydi. public class Enrollment { public int EnrollmentID { get; set; } public int CourseID { get; set; } //StdntID is not following code first conventions name public int StdntID { get; set; } public Grade? Grade { get; set; } public virtual Course Course { get; set; } public virtual Student Student { get; set; } } public class Student { public int ID { get; set; } public string LastName { get; set; } public string FirstMidName { get; set; } public DateTime EnrollmentDate { get; set; } public virtual StudentLogIn StudentLogIn { get; set; } public virtual ICollection<Enrollment> Enrollments { get; set; } } Bunday holda, Fluent API yordamida birdan ko'pga munosabatlarni sozlash uchun quyidagi kodda ko'rsatilganidek, HasForeignKey usulidan foydalanishingiz kerak. protected override void OnModelCreating(DbModelBuilder modelBuilder) { //Configure default schema modelBuilder.HasDefaultSchema("Admin"); //Configure FK for one-to-many relationship modelBuilder.Entity<Enrollment>() .HasRequired<Student>(s ⇒ s.Student) .WithMany(t ⇒ t.Enrollments) .HasForeignKey(u ⇒ u.StdntID); } Ma'lumotlar bazasi yaratilganda, quyidagi rasmda ko'rsatilganidek, munosabatlar yaratilganligini ko'rasiz. Yuqoridagi misolda HasRequired usuli Student navigatsiya xususiyati Null bo'lishi kerakligini bildiradi. Shunday qilib, har safar Roʻyxatdan oʻtishni qoʻshganingizda yoki yangilaganingizda Talabani Roʻyxatdan oʻtish obyekti bilan belgilashingiz kerak. Buni hal qilish uchun biz HasRequired usuli o'rniga HasOptional usulidan foydalanishimiz kerak. Ko'pdan ko'pga munosabatni sozlang Ikkala jadvaldagi har bir yozuv boshqa jadvaldagi yozuvlarning istalgan soniga (yoki hech qanday yozuvga) tegishli bo'lishi mumkin. Birlamchi kaliti A jadvali va B jadvalidagi tashqi kalitlardan iborat bo'lgan uchinchi jadvalni belgilash orqali bunday munosabatni yaratishingiz mumkin. Masalan, Talabalar jadvali va Kurs jadvali ko'p-ko'p munosabatiga ega. Quyida Talaba va Kurs o'rtasida ko'p-toman aloqasi bo'lgan Talaba va Kurs sinflari keltirilgan, chunki ikkala sinfda navigatsiya xususiyatlari Talabalar va Kurslar to'plamidir. Boshqacha qilib aytadigan bo'lsak, bir korxona boshqa ob'ekt to'plamiga ega. public class Student { public int ID { get; set; } public string LastName { get; set; } public string FirstMidName { get; set; } public DateTime EnrollmentDate { get; set; } public virtual ICollection<Course> Courses { get; set; } public virtual ICollection<Enrollment> Enrollments { get; set; } } public class Course { public int CourseID { get; set; } public string Title { get; set; } public int Credits { get; set; } public virtual ICollection<Student> Students { get; set; } public virtual ICollection<Enrollment> Enrollments { get; set; } } Talaba va Kurs oʻrtasidagi koʻpdan koʻpga munosabatni sozlash uchun quyidagi kodda koʻrsatilganidek, Fluent API dan foydalanishingiz mumkin. protected override void OnModelCreating(DbModelBuilder modelBuilder) { //Configure default schema modelBuilder.HasDefaultSchema("Admin"); // Configure many-to-many relationship modelBuilder.Entity<Student>() .HasMany(s ⇒ s.Courses) .WithMany(s ⇒ s.Students); } Ma'lumotlar bazasi yaratilganda birlashma jadvalini yaratish uchun standart Code First konventsiyalaridan foydalaniladi. Natijada quyidagi rasmda ko'rsatilganidek, StudentCourses jadvali Course_CourseID va Student_ID ustunlari bilan yaratiladi. Agar siz jadvalning birlashma nomini va jadvaldagi ustunlar nomlarini belgilashni istasangiz, Map usuli yordamida qo'shimcha konfiguratsiya qilishingiz kerak. protected override void OnModelCreating(DbModelBuilder modelBuilder) { //Configure default schema modelBuilder.HasDefaultSchema("Admin"); // Configure many-to-many relationship modelBuilder.Entity<Student>() .HasMany(s ⇒ s.Courses) .WithMany(s ⇒ s.Students) .Map(m ⇒ { m.ToTable("StudentCoursesTable"); m.MapLeftKey("StudentID"); m.MapRightKey("CourseID"); }); } Ma'lumotlar bazasi qachon yaratilganligini, jadval va ustunlar nomi yuqoridagi kodda ko'rsatilganidek yaratilganligini ko'rishingiz mumkin.