連線資料庫取得模型資料來源 – ADO.NET

ASP.NET Core Web 應用開發–使用 MVC 框架 / PART I MVC 入門 / MVC - Model 的部份 / 連線資料庫取得模型資料來源 – ADO.NET

實務開發透過連線伺服器資料庫以取得資料來源,這一部份主要可以透過ADO.NET或是Entity Framework進行支援。

準備資料來源

為了方便測試,這裏直接以SQL Server Express 的Microsoft SQL Server Express LocalDB配置需要的測試資料庫,開啟Visual Studio的「SQL Server物件總管」,並且於其中的「資料庫」節點中,開啟「加入新資料庫」對話方塊,以建立新的資料庫KTBooks。

完成之後利用以下的語法建立Book資料表結構。

CREATE TABLE [dbo].[Book] (
    [BookId]          INT            IDENTITY (1, 1) NOT NULL,
    [Title]           NVARCHAR (50)  NOT NULL,
    [ISBN]            NVARCHAR (50)  NULL,
    [PublicationDate] DATETIME2 (7)  NULL,
    [Price]           DECIMAL (18)   NULL,
    [Pages]           INT            NULL,
    [ImageUrl]        NVARCHAR (500) NULL,
    [CategoryId]      INT            NULL
);

以如下的SQL指令建立測試資料。

INSERT INTO [dbo].[Book] 
([BookId], [Title], [ISBN], [PublicationDate], [Price], [Pages], [ImageUrl], [CategoryId]) 
VALUES 
(10001, N'C# 2010 精要剖析', N'9789572239223', N'2011-07-08 00:00:00', CAST(520 AS Decimal(18, 0)), 520, NULL, 1004)
INSERT INTO [dbo].[Book] 
([BookId], [Title], [ISBN], [PublicationDate], [Price], [Pages], [ImageUrl], [CategoryId]) 
VALUES 
(10002, N'Silverlight:ASP.NET與AJAX開發實務', N'9789866761126', N'2007-09-13 00:00:00', CAST(480 AS Decimal(18, 0)), NULL, NULL, 1001)

... 

以下是建立的資料表內容。

引用ADO.NET存取資料

現在回到專案,首先從NuGet安裝Microsoft.Data.SqlClient套件,以支援ADO.NET資料存取。

建立新的控制器檔案AdoController.cs,於配置以下的程式碼:

using HelloMVC.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Data.SqlClient; 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace HelloMVC.Controllers
{
    public class AdoController : Controller
    {
        public IActionResult Index()
        {
            var books = GetBooks(); 
            return View(books);
        }
        public List<KTBook> GetBooks()
        {
            var books = new List<KTBook>();
            var connstring =
                @"Data Source=(localdb)\mssqllocaldb;
                Initial Catalog=KTBooks;Integrated Security=True";
            var sql = "SELECT * FROM Book";
            using (var conn = new SqlConnection(connstring))
            {               
                conn.Open();
                var cmd = new SqlCommand(sql,conn);
                SqlDataReader reader = cmd.ExecuteReader();
                while (reader.Read())
                {
                    books.Add(new KTBook
                    {
                        BookId = Convert.ToInt32(reader["BookId"]), 
                        Title = reader["Title"].ToString(),
                        ISBN = reader["ISBN"].ToString(),
                        PublicationDate =Convert.ToDateTime(reader["PublicationDate"]),
                        Price = Convert.ToDecimal(reader["Price"]),
                        Pages = reader["Pages"] is DBNull ? 
                    -1 : 
                    Convert.ToInt32(reader["Pages"])
                    }); 
                    
                }
            }
            return books; 
        }
    }
}

一開始引用Microsoft.Data.SqlClient命名空間以支援ADO.NET。

定義GetBooks()取得KTBooks資料庫中的Book資料表資料,封裝成List<KTBook>集合物件進行回傳,於其中透過ADO.NET建立資料連線物件conn,串接資料庫KTBooks,然後透過Command物件傳送SQL敘述,取得Redaer物件。

SQL敘述僅作簡單的示範,回傳所有的Book資料表內容,而while迴圈依序讀取每一筆Reader指定欄位資料,進行KTBook對應的相容屬性型態轉型,逐一封裝成為KTBook物件,最後儲存成為List<KTBook>物件回傳。

ADO.NET回傳的資料是沒有型別資訊的,因此必須小心的逐一轉型適的相容型態,甚至包含 null 值的問題,都必須處理,這也是建議在新專案儘量改用Entity Framework的原因之一,特別是在愈複雜的中大型專案。

在Index動作方法中,引用GetBooks(),取出包含所有Book資料表的List<KTBook>物件,儲存於books變數,傳入View(),以支援檢視檔案的視覺輸出處理,這裏請參考「MVC - Model 的部份」。

沒有留言: