Thực hành Lập trình ado.net cơ bản: Tạo bảng, kết nối, đọc dữ liệu

    0

    Trong bài học này chúng ta sẽ bắt đầu bằng nội dung thực hành: tạo bảng dữ liệu trong Sql Server, viết code để kết nối và đọc-ghi dữ liệu với ADO.NET. Mục tiêu của bài học là giúp bạn có cảm nhận thực tế đầu tiên về lập trình ADO.NET và cách làm việc với cơ sở dữ liệu từ chương trình. Nó sẽ giúp bạn dễ hình dung về ADO.NET hơn khi chúng ta trao đổi các nội dung lý thuyết trong bài sau.

    Trong bài học trước chúng ta đã cài đặt các công cụ cần thiết để học ADO.NET. Chúng ta cũng đã tạo một cơ sở dữ liệu tên là Contacts để phục vụ thực hành và làm ví dụ. Trong bài học này chúng ta sẽ tạo các bảng dữ liệu cần thiết. Sau đó sẽ dùng ADO.NET để viết chương trình đơn giản đầu tiên đọc-ghi dữ liệu với cơ sử dữ liệu Contacts.

    Đừng lo nếu bạn không hiểu hết code của bài này. Chúng ta sẽ còn quay lại và phân tích chi tiết các vấn đề sau khi giới thiệu các phần lý thuyết liên quan.

    [signinlocker id=”16252″]

    Tạo bảng dữ liệu trong SSMS và SQL Server

    Cấu trúc các bảng dữ liệu

    Cơ sở dữ liệu Contacts đã tạo ở bài trước dùng để lưu trữ thông tin liên hệ của khách hàng. Mỗi bản ghi trong danh bạ chứa các thông tin:

    • Tên liên hệ (contact name),
    • Biệt danh (alias),
    • Họ + đệm (first name),
    • Tên (last name),
    • Ngày sinh (birth day),
    • Danh sách email, mỗi email trong danh sách bao gồm loại email (cá nhân, công việc, tổ chức) và địa chỉ email tương ứng.
    • Danh sách số điện thoại, mỗi thông tin về điện thoại bao gồm loại (cá nhân, công việc), và số điện thoại tương ứng.

    Chúng ta sẽ tạo các bảng với cấu trúc như sau cho cơ sở dữ liệu Contacts.

    Cấu trúc bảng dữ liệu tổng quát
    Cấu trúc bảng dữ liệu tổng quát
    Cấu trúc bảng dữ liệu chi tiết
    Cấu trúc bảng dữ liệu chi tiết

    Tạo bảng dữ liệu từ SSMS

    Click phải chuột vào cơ sở dữ liệu Contacts và chọn New Query

    Tạo truy vấn mới từ SSMS
    Tạo truy vấn mới từ SSMS

    Copy đoạn mã SQL sau đây dán vào cửa sổ truy vấn và ấn F5 để chạy.

    USE [Contacts]
    GO
    /****** Object:  Table [dbo].[Contacts] ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    CREATE TABLE [dbo].[Contacts](
    	[Id] [int] IDENTITY(1,1) NOT NULL,
    	[ContactName] [nvarchar](max) NULL,
    	[Alias] [nvarchar](max) NULL,
    	[FirstName] [nvarchar](max) NULL,
    	[LastName] [nvarchar](max) NULL,
    	[DateOfBirth] [datetime] NOT NULL,
     CONSTRAINT [PK_dbo.Contacts] PRIMARY KEY CLUSTERED 
    (
    	[Id] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
    GO
    /****** Object:  Table [dbo].[Emails] ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    CREATE TABLE [dbo].[Emails](
    	[Id] [int] IDENTITY(1,1) NOT NULL,
    	[Type] [nvarchar](max) NULL,
    	[EmailAddress] [nvarchar](max) NULL,
    	[Contact_Id] [int] NULL,
     CONSTRAINT [PK_dbo.Emails] PRIMARY KEY CLUSTERED 
    (
    	[Id] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
    GO
    /****** Object:  Table [dbo].[Phones]  ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    CREATE TABLE [dbo].[Phones](
    	[Id] [int] IDENTITY(1,1) NOT NULL,
    	[Type] [nvarchar](max) NULL,
    	[Number] [nvarchar](max) NULL,
    	[Contact_Id] [int] NULL,
     CONSTRAINT [PK_dbo.Phones] PRIMARY KEY CLUSTERED 
    (
    	[Id] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
    GO
    ALTER TABLE [dbo].[Emails]  WITH CHECK ADD  CONSTRAINT [FK_dbo.Emails_dbo.Contacts_Contact_Id] FOREIGN KEY([Contact_Id])
    REFERENCES [dbo].[Contacts] ([Id])
    GO
    ALTER TABLE [dbo].[Emails] CHECK CONSTRAINT [FK_dbo.Emails_dbo.Contacts_Contact_Id]
    GO
    ALTER TABLE [dbo].[Phones]  WITH CHECK ADD  CONSTRAINT [FK_dbo.Phones_dbo.Contacts_Contact_Id] FOREIGN KEY([Contact_Id])
    REFERENCES [dbo].[Contacts] ([Id])
    GO
    ALTER TABLE [dbo].[Phones] CHECK CONSTRAINT [FK_dbo.Phones_dbo.Contacts_Contact_Id]
    GO
    

    Tương tự, nhập một số dữ liệu bằng script sau:

    USE [Contacts]
    GO
    SET IDENTITY_INSERT [dbo].[Contacts] ON
    INSERT INTO [dbo].[Contacts] ([Id], [ContactName], [Alias], [FirstName], [LastName], [DateOfBirth]) VALUES (1, N'Donald Trump', N'trump', N'Trump', N'Donald', N'2019-06-26 12:21:29')
    INSERT INTO [dbo].[Contacts] ([Id], [ContactName], [Alias], [FirstName], [LastName], [DateOfBirth]) VALUES (2, N'Barack Obama', N'obama', N'Obama', N'Barack', N'2019-06-26 12:22:00')
    SET IDENTITY_INSERT [dbo].[Contacts] OFF
    GO
    SET IDENTITY_INSERT [dbo].[Emails] ON
    INSERT INTO [dbo].[Emails] ([Id], [Type], [EmailAddress], [Contact_Id]) VALUES (1, N'Work', N'trump@gmail.com', 1)
    INSERT INTO [dbo].[Emails] ([Id], [Type], [EmailAddress], [Contact_Id]) VALUES (2, N'Home', N'donald@gmail.com', 1)
    INSERT INTO [dbo].[Emails] ([Id], [Type], [EmailAddress], [Contact_Id]) VALUES (3, N'Work', N'obama@gmail.com', 2)
    INSERT INTO [dbo].[Emails] ([Id], [Type], [EmailAddress], [Contact_Id]) VALUES (4, N'Home', N'barack@gmail.com', 2)
    SET IDENTITY_INSERT [dbo].[Emails] OFF
    SET IDENTITY_INSERT [dbo].[Phones] ON
    INSERT INTO [dbo].[Phones] ([Id], [Type], [Number], [Contact_Id]) VALUES (1, N'Work', N'0123.456.789', 1)
    INSERT INTO [dbo].[Phones] ([Id], [Type], [Number], [Contact_Id]) VALUES (2, N'Home', N'0987.654.321', 1)
    SET IDENTITY_INSERT [dbo].[Phones] OFF
    GO

    Các bạn lưu ý rằng đây không phải là một tài liệu về SQL nên chúng ta không mất thời gian giải thích các khối mã SQL ở trên. Chúng tôi giả định rằng khi theo khóa học này bạn đã học và nắm được các vấn đề cơ bản của cơ sở dữ liệu quan hệ và ngôn ngữ SQL.

    Thực hành 1 – lập trình ứng dụng ADO.NET đầu tiên

    Chương trình ứng dụng ADO.NET đầu tiên này sẽ đọc số lượng contact có trong cơ sở dữ liệu và in ra màn hình.

    Tạo một solution mới tên là HelloAdoNet với một project thuộc loại Console App (.NET framework) như dưới đây

    Tạo solution và project cho ví dụ 1

    Mở file Program.cs và viết code như sau:

    using System;
    using System.Data.SqlClient;
    namespace Example01
    {
        internal class Program
        {
            private static void Main(string[] args)
            {
                // object đảm nhiệm việc kết nối
                var connection = new SqlConnection
                {
                    // chuỗi ký tự chứa tham số phục vụ kết nối
                    ConnectionString = @"Data Source=.\sqlexpress;Initial Catalog=Contacts;Integrated Security=True"
                };
                // object đảm nhiệm việc thực thi truy vấn
                var command = new SqlCommand()
                {
                    Connection = connection,
                    CommandText = "SELECT COUNT(*) FROM CONTACTS"
                };
    
                // thử mở kết nối
                connection.Open();
                // thực thi truy vấn và lấy kết quả
                var res = (int)command.ExecuteScalar();
                // đóng kết nối
                connection.Close();
                Console.WriteLine($"{res} contacts found in the database");
                Console.ReadLine();
            }
        }
    }

    Dịch và chạy thử chương trình

    Kết quả chạy chương trình ADO.NET đầu tiên
    Chương trình ado.net đầu tiên: đọc số bản ghi từ cơ sở dữ liệu

    Chúc mừng bạn đã viết được chương trình đầu tiên với ADO.NET. Chương trình minh họa cách thức làm việc với cơ sở dữ liệu thông qua ADO.NET để đọc một giá trị duy nhất.

    Phương thức ExecuteScalar của SqlCommand chỉ trả lại duy nhất một giá trị thuộc kiểu object. Do đó, nó chỉ phù hợp để đọc các giá trị thống kê từ Sql Server.

    Chương trình rất đơn giản và code hoàn toàn không thực hiện các thao tác kiểm tra gì. Tạm thời chúng ta sẽ không phân tích code của chương trình. Trong các bài học tiếp theo khi học lý thuyết về ADO.NET chúng ta sẽ quay lại phân tích chi tiết.

    Thực hành 2 – đọc các bản ghi từ cơ sở dữ liệu

    Tạo project thứ hai cũng kiểu Console App (.NET Framework) trong cùng solution và đặt tên là Example02. Thiết lập để Example02 làm startup project.

    Mở file Program.cs và code như sau:

    using System;
    using System.Data;
    using System.Data.SqlClient;
    namespace Example02
    {
        internal class Program
        {
            private static void Main(string[] args)
            {
                var connectionString = @"Data Source=.\sqlexpress;Initial Catalog=Contacts;Integrated Security=True";
                var connection = new SqlConnection(connectionString);
                var command = new SqlCommand("SELECT * FROM CONTACTS", connection);
                connection.Open();
                var dataReader = command.ExecuteReader(CommandBehavior.CloseConnection);
                if (dataReader.HasRows)
                {
                    while (dataReader.Read())
                    {
                        var id = dataReader.GetInt32(0);
                        var contactName = dataReader.GetString(1);
                        var alias = dataReader.GetString(2);
                        Console.WriteLine($"[{id}] {contactName} ({alias})");
                    }
                }
                Console.ReadLine();
            }
        }
    }

    Dịch và chạy thử chương trình:

    Chương trình Ado.NET đọc các bản ghi từ cơ sở dữ liệu
    Chương trình Ado.NET đọc các bản ghi từ cơ sở dữ liệu

    Chúc mừng bạn đã xây dựng được một chương trình có khả năng đọc được trọn vẹn các bản ghi từ bảng dữ liệu của SQL Server. Chương trình này khác biệt ở chỗ nó đọc được tất cả các bản ghi từ một bảng dữ liệu.

    Các bạn có thể để ý thấy là các công đoạn ban đầu (như chuẩn bị chuỗi kết nối, tạo object connection, command, mở kết nối) không khác biệt gì so với ví dụ 1. Chỉ là chúng ta sử dụng các overload khác của hàm tạo với mục đích minh họa.

    Ở giai đoạn đọc dữ liệu, thay vì sử dụng phương thức ExecuteScalar, chúng ta dùng phương thức ExecuteReader của SqlCommand để đọc cả bản ghi. Để đọc thông tin của từng trường trong bản ghi chúng ta sử dụng số thứ tự của cột dữ liệu và chuyển đổi về kiểu dữ liệu tương ứng của .NET thông qua các phương thức Get (GetInt32, GetString).

    Thực hành 3 – DataAdapter và DataTable

    Chúng ta tạo tiếp một project thứ ba đặt tên là Example03 tương tự như hai ví dụ trên và code như sau:

    using System;
    using System.Data;
    using System.Data.SqlClient;
    namespace Example03
    {
        internal class Program
        {
            private static void Main(string[] args)
            {
                var connectionString = @"Data Source=.\sqlexpress;Initial Catalog=Contacts;Integrated Security=True";
                var dataTable = new DataTable();
                using (var connection = new SqlConnection(connectionString))
                {
                    var command = connection.CreateCommand();
                    command.CommandText = "SELECT * FROM CONTACTS";
                    var dataAdapter = new SqlDataAdapter(command);
                    dataAdapter.Fill(dataTable);
                }
                foreach (DataRow r in dataTable.Rows)
                {
                    var id = (int)r["Id"];
                    var contactName = (string)r["ContactName"];
                    var alias = (string)r["Alias"];
                    Console.WriteLine($"[{id}] {contactName} ({alias})");
                }
                Console.ReadLine();
            }
        }
    }

    Dịch và chạy chương trình sẽ thu được kết quả giống hệt như ví dụ 2.

    Ở đây chúng ta đã sử dụng một mô hình làm việc hoàn toàn khác. Hai ví dụ trên chúng ta sử dụng mô hình Connected của ADO.NET, còn ở ví dụ này chúng ta sử dụng mô hình Disconnected. Sự khác biệt giữa hai mô hình này sẽ được giải thích chi tiết ở bài sau – kiến trúc ADO.NET.

    Kết luận

    Trong bài học này chúng ta đã cùng nhau bước đầu làm quen với lập trình ADO.NET thông qua thực hiện một số ví dụ minh họa đơn giản. Các ví dụ này chỉ có mục đích giúp bạn có cảm nhận ban đầu về lập trình ADO.NET.

    Bạn nên bỏ thời gian để “nghịch” với các code trên như thay đổi tham số, thử nghiệm các overload khác nhau của hàm tạo, thử kết nối và làm việc với các cơ sử dữ liệu khác (nếu có).

    Trong các bài học tiếp theo chúng ta sẽ lần lượt đi vào từng vấn đề cụ thể của lập trình ADO.NET.

    [/signinlocker]

    Theo dõi
    Thông báo của
    guest

    0 Thảo luận
    Phản hồi nội tuyến
    Xem tất cả bình luận