Entity Framework II

Өмнөх хичээлд бид өгөгдлийн сантай ажиллах Entity Framework технологи гэж юу болох, өгөгдлийн сантай ажиллахад шаардлагатай хэрэгслүүд, тэдгээрийг хэрхэн суулгахыг үзээд өгөгдлийн сан үүсгэн түүнд хандах жижигхэн програмыг зохиосон. Энэ хичээлээр өмнөх хичээлд бичсэн програмын код хэрхэн ажиллаж байгааг үргэлжлүүлэн судлах болно. Програмын кодыг сануулбал

using DbDemo.Properties;
using System;
using System.Data;
using System.Data.SqlClient;

namespace DbDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            using (IDbConnection connection = new SqlConnection(Settings.Default.DbConnect))
            {
                IDbCommand command = new SqlCommand("SELECT * FROM t_customers");
                command.Connection = connection;
                connection.Open();
                IDataReader reader = command.ExecuteReader();
                while (reader.Read())
                {
                    Console.WriteLine("Id: {0}\t Нэр: {1}", reader.GetInt32(0),
                        reader.GetString(1));
                }
            }
            Console.ReadLine();
        }
    }
}

гэж байгаа.

Програм өгөгдлийн сангаас мэдээлэл авах учраас түүнтэй холбогдохын тулд IDbConnection интерфейсийг хэрэгжүүлсэн классын шинэ хувийг үүсгэнэ. .NET фреймворкт энэ интерфейсийн хэрэгжүүлэлт стандартаар орсон байдаг тул бид програмын эхний мөрөнд IDbConnection интерфейсийн хэрэгжүүлэлт болох SqlConnection классын хувийг үүсгэсэн. Классын байгуулагчид холболтын мөр шаардлагатай тул түүнийг App.config файлаас Settings классаар дамжуулан Settings.Default.DbConnect гэж авна. Settings классыг боловсруулалтын орчин програмын тохиргоог үүсгэхэд автоматаар төслийн Settings.settings дотор байрлах Settings.Desinger.cs файлд тодорхойлон өгдөг. Програмын эхний мөрөөр холболтын мөрийг өгөн шинэ холболтын хувийг бий болгосон. Дараа нь бид өгөгдлийн сан гүйцэтгэх командыг IDbCommand command = new SqlCommand("SELECT * FROM t_customers"); гэж заан өгнө. Энд бид бас л .NET фреймворкт IDbCommand интерфейсийн стандарт хэрэгжүүлэлт болох SqlCommand классыг ашигласан. Классын байгуулагчид өгөгдлийн сан биелүүлэх ёстой Sql шаардлагыг өгнө. Шаардлага бол t_customers хүснэгтийн бүх мэдээллийг татан авах. Үүсгэсэн командын холболтын шинжид өгөгдлийн сангийн холбоосыг command.Connection = connection; гэж олгоно. Өгөгдлийн сантай ажиллахын өмнө түүний холболтыг нээх хэрэгтэй. Үүнийг connection.Open(); оператор гүйцэтгэнэ. Дараагийн оператор SQL Server өгөгдлийн санд манай командыг дамжуулан гүйцэтгүүлээд өгөгдлийн багцыг буцаан авна. Цаашаа серверээс татан авсан өгөгдлүүдийн багцыг циклээр гүйлгэн уншиж reader -ийн аргуудыг ашиглан дэлгэц дээр харуулна. reader.GetInt32(0) арга хүснэгтийн эхний баганы өгөгдлийг Int төрөлд харин reader.GetString(1) арга хүснэгтийн хоёрдугаар баганы өгөгдлийг мөр төрлийн болгож байгаа юм.
Өгөгдлийн сантай ийм аргачлалаар ажиллахад олон тооны дутагдалтай талууд байгааг та анзаарч байгаа байх. Дээрх код бол Entity Framework технологийг ашигласан хэлбэр биш өгөгдлийн сантай ADO.NET -ийг ашиглан доод түвшинд харьцаж буй хэлбэр болно. Гэхдээ Entity Framework ч эцсийн түвшиндээ өгөгдлийн сантай бас л ийм хэлбэрээр харьцдаг ч програм зохиогчид ажиллахад таатай орчинг бий болгодогоороо л давуу. Өгөгдлийн сантай харьцсан дээрх кодод ямар дутагдлууд байгааг дурдвал:

  1. Sql шаардлагын бичлэгийг C# код дотор "SELECT * FROM t_customers" гэж шууд мөр хэлбэрээр ашиглаж байгаа. Sql шаардлагын бичлэгт хүснэгт, баганы нэрийг буруу бичих зэргээр дүрмийн алдааг маш амархан гаргах магадлалтай. Үүнээс гадна кодод рефакторинг хийх бараг боломжгүй. Өөрөөр хэлбэл шаардлага зөв бичигдсэн эсэхийг шалгах боломжгүй.  
  2. Бид холболтыг хэзээ нээх, хэзээ хаах гэх мэтээр удирдах ажиллагааг хянаж байх хэрэгтэй. Манай холболтын обьект удирдлагагүй нөөцөд хамааралтай учраас бид түүний удирдлагыг өөрсдөө хянах ёстой. Энэ бүгдийг хянах нь тийм ч хүнд биш тул онцын хүндрэлгүй.   
  3. Бид төрөлжөөгүй үр дүнтэй ажиллана. Энэ бол хамгийн төвөгтэй асуудал. Програмаас ExecuteReader() аргыг дуудахад түүнээс ямар зүйлүүдийг агуулсан өгөгдлийн багцыг буцаахыг бид мэдэхгүй учраас түүнийг гүйлгэн уншихдаа аль хүснэгтийн ямар багана ямар төрлийн өгөгдлүүдийг хадгалж байгааг урьдчилан мэдэж байх хэрэгтэй. ORM технологи гарч ирэхээс өмнө програм зохиогчид бүгд л ийм төрөлжөөгүй обьектыг аван тохирох төрөлд нь шилжүүлэн ажиллаж байсан.
  4. Өгөгдлийн сангаас авсан мэдээллүүдийг дэлгэц дээр харуулж болох ч өгөгдлүүдтэй програм цаашид ажиллаж хэрэгтэй болбол яах вэ?

гээд асуудлууд байна аа. Програмд өгөгдлийн сангаас мэдээллийг татан авч үзүүлэхийн дээр түүнтэй ажиллах шаардлага байнга гардаг. Үүнийг шийдэхийн тулд ямар нэгэн классыг бичээд өгөгдлүүдийг тухайн классын хувьд хадгалаад дараа нь энэ хувьтай ажиллах арга байна. Үүнийг хэрхэн хэрэгжүүлэхийг авч үзье. Програмдаа t_customers хүснэгтийн багануудад харгалзсан шинжүүдийг

namespace DbDemo
{
    public class CustomerInfo
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
}

тодорхойлсон CustomerInfo классыг нэмээд удирдах програмын кодын өгөгдлийн сангаас мэдээллийг татан авах кодыг

        private static List<CustomerInfo> GetCustomers()
        {
            using (IDbConnection connection = new SqlConnection(Settings.Default.DbConnect))
            {
                IDbCommand command = new SqlCommand("SELECT * FROM t_customers");
                command.Connection = connection;
                connection.Open();
                IDataReader reader = command.ExecuteReader();
                List<CustomerInfo> customers = new List<CustomerInfo>();
                while (reader.Read())
                {
                    CustomerInfo customer = new CustomerInfo();
                    customer.Id = reader.GetInt32(0);
                    customer.Name = reader.GetString(1);
                    customers.Add(customer);
                }
                return customers;
            }
        }

GetCustomers аргад оруулъя. Арга өмнөх кодтой бараг ижилхэн үйлдлийг хийх ч үр дүнг дэлгэц рүү гаргахын оронд түүнийг CustomerInfo төрлийн жагсаалт болгоно. Ингэснээр бид өгөгдлийн сангаас буцаах төрөлжөөгүй үр дүнг төрөлжүүлсэн жагсаалт болгож байгаа хэрэг. Дараа нь бид харилцагчдын жагсаалтыг консолд үзүүлэх аргад

        static void Main(string[] args)
        {
            var customers = GetCustomers();

            foreach (var customer in customers)
            {
                Console.WriteLine("Id: {0}\t Нэр: {1}", customer.Id,
                        customer.Name);
            }
            Console.ReadLine();
        }

гэж ашиглана. Одоо бид хэрэглээний кодын хүрээнд төрөлжсөн өгөгдлүүдтэй ажиллах боломжтой болсон. Програмыг ажлуулбал

өмнөхтэй ижил үр дүнг авна. Дээрх жишээнд бидний хийсэн зүйл бол төрөлжүүлээгүй өгөгдлүүдийг CustomerInfo класст оруулан тэдгээрийг ашиглахад эвтэйхэн болгон төрөлжүүлсэн явдал байлаа. Эндээс манай t_customers хүснэгт CustomerInfo классууд нилээд ижилхэн төрлийнх гэдгээс үүдэн өгөгдлийн сангийн хүснэгтүүдээс үндэслэн манай завсарын классуудыг эсхүл манай классуудааас өгөгдлийн сангийн хүснэгтүүдийг автоматаар үүсгэдэг хэрэгсэл байвал хичнээн тустай гэсэн санаа төрнө. Entity Framework болон бусад ORM технологийн гол санаа нь өгөгдлийн сангийн обьектууд ба хэрэглэний классууд хооронд харьцааг бий болгох юм. Энэ хүртэл үзсэн зүйлүүд бол өгөгдлийн сантай ажиллах уламжлалт аргыг ойлгоход зориулагдсан байлаа. ORM технологийг хэрэглэхгүйгээр өгөгдлийн сантай ажиллах тийм ч амархан зүйл биш гэдгийг харуулах зорилгоор дээрх жишээг авч үзсэн юм.

Өгөгдлийн сантай ORM технологийг ашиглан хэрхэн ажиллахыг дараагийн хичээлээс үзээрэй.

Мэдээлэл таалагдсан бол найзуудтайгаа хуваалцаарай.

  Нээгдсэн тоо: 416 Төлбөртэй

Төрөл бүрийн классууд, структуруудийг тусдаа сан хэлбэрээр бүрдүүлэн компиляц хийн dll файлд багцлаад дараа нь өөр төслүүдэд оруулан ашиглах нь элбэг байдаг. Үүний ачаар програмд олон дахин ашиглагдах ижил ажиллагаатай хэсгүүдийг сан хэлбэрээр тодорхойлоод төрөл бүрийн төслүүдэд оруулах эсхүл өөр боловсруулагч нарт ашиглуулах боломж бүрдэнэ.

  Нээгдсэн тоо: 235 Төлбөртэй

Универсал параметрүүд ашиглан ерөнхийлөгдсөн классийг дурын төрлөөр төрөлжүүлж болно. Хааяа төрлийг тодорхой болгох шаардлага үүсдэг. Жишээ нь бидэнд мэдээллийг илэрхийлэх

class Message
{
    public string Text { get; } // мэдээллийн текст
    public Message(string text)
    {
        Text = text;
    }
}

Message класс байлаа гэе. Мэдээллийн Message хэлбэрийн обьектоор дамжуулах аргыг тодорхойлохыг хүсвэл эхний ээлжинд

  Нээгдсэн тоо: 373 Бүртгүүлэх

Өмнөх хичээлүүдийн бүх жишээнүүдэд тогтмол тооны параметерүүдийг ашигласан. Харин params түлхүүр үгийг ашиглан аргад тодорхойгүй тоотой параметрийг дамжуулж болно.

void Sum(params int[]  numbers)
{
    int result = 0;
    foreach (var n in numbers)
    {
        result += n;
    }
    Console.WriteLine(result);
}
 
int[] nums = { 1, 2, 3, 4, 5};
Sum(nums);
Sum(1, 2, 3, 4);
Sum(1, 2, 3);
Sum();

  Нээгдсэн тоо: 344 Бүртгүүлэх

Зуучлагч (Mediator) нь олон тооны обьектууд бие биетэйгээ холбоос үүсгэхгүйгээр харилцан ажиллах боломжийг хангах загварчлалын хэв юм. Ингэснээр обьектуудын харилцан ажиллагааны сул холбоосыг бий болгоно.

Хэвийг хаана ашиглах

  • Холбоонууд нарийн, ээдрээтэй олон тооны харилцан холбоотой обьектууд байх үед.
  • Өөр обьектуудтай нягт холбоотойгоос үүдэн дахин ашиглахад хүндрэлтэй обьектыг дахин ашиглах шаардлага гарах үед

Хэвийг UML диаграмаар дараах байдлаар тодорхойлно.

patt_21_01

Үйл явдал /event/ тодорхой үйлдэл хийгдсэн талаар системд мэдэгддэг. Хэрвээ бид энэхүү үйлдлийг ажиглах хэрэгтэй бол яг энд…

Нээгдсэн тоо : 129

 

Манай төсөл олон хуудсуудтай болон тэдгээрийн хооронд динамикаар шилжилт хийж байгаа ч тухайн үед шилжилт хийгдсэн хуудаст тохирох…

Нээгдсэн тоо : 190

 

Зочин (Visitor) паттерн классуудыг өөрчлөхгүйгээр тэдгээрийн обьектуудын үйлдлийг тодорхойлох боломжийг олгоно. Зочин хэвийг ашиглахдаа классуудын хоёр ангилалыг тодорхойлно.…

Нээгдсэн тоо : 158

 

Лямбда-илэрхийлэл нь нэргүй аргын хураангуй бичилтийг илэрхийлнэ. Лямбда-илэрхийлэл утга буцаадаг, буцаасан утгыг өөр аргын…

Нээгдсэн тоо : 285

 

Кодийн сайжруулалт /рефакторинг/ хичээлээр програмийн кодоо react -ийн зарчимд нийцүүлэн компонентод салгасан.…

Нээгдсэн тоо : 315

 

Хадгалагч (Memento) хэв обьектын дотоод төлвийг түүний гадна гаргаж дараа нь хайрцаглалтын зарчмыг зөрчихгүйгээр обьектыг сэргээх боломжийг олгодог.

Нээгдсэн тоо : 320

 

Делегаттай нэргүй арга нягт холбоотой. Нэргүй аргуудыг делегатийн хувийг үүсгэхэд ашигладаг.
Нэргүй аргуудын тодорхойлолт delegate түлхүүр үгээр…

Нээгдсэн тоо : 386

 

Математикт харилцан урвуу тоонууд гэж бий. Ямар нэгэн тооны урвуу тоог олохдоо тухайн тоог сөрөг нэг зэрэг дэвшүүлээд…

Нээгдсэн тоо : 387

 

Төсөлд react-router-dom санг оруулан чиглүүлэгчдийг бүртгүүлэн тохируулсан Санг суулган тохируулах хичээлээр бид хуудас…

Нээгдсэн тоо : 463

 
Энэ долоо хоногт

Нээгдсэн тоо : 746

 

Аяга, стакан, ваар, лаазанд сүү, ундаа, квас, ус байжээ. Аяганд ус, сүү байхгүй, ундаатай сав ваар болон квастай савны дунд, лаазанд ундаа, усны аль нь ч байхгүй, стакан лааз ба сүүтэй савтай зэрэгцэн байрласан бол ямар саванд ямар шингэнийг хийсэн бэ.

Жич: Маш сонирхолтой гоё бодлого. Оролдоод үзээрэй.

Нээгдсэн тоо : 1074

 

илэрхийллийн хялбарчил.

Нээгдсэн тоо : 325