Sử dụng ADO.NET kết nối tới cơ sở dữ liệu Oracle
Trong bài này, chúng ta sẽ tìm hiểu cách sử dụng Sử dụng ADO.NET kết nối tới cơ sở dữ liệu Oracle thông qua sử dụng .NET Framework Data Provider dành cho Oracle nằm trong không gian tên System.Data.OracleClient được cung cấp sẵn trong thư viện .Net Framework của Microsoft bằng ngôn ngữ lập trình C#.
Đề thử nghiệm bài viết này chúng ta cần một cơ sở dữ liệu (database ) oracle đã được cài đặt sẵn . Hãy xem xét ví dụ dưới đây sử dụng ngôn ngữ C# để truy cập tới 1 bảng khách hàng CUSTOMERDEMO được tạo trong 1 Schema nào đó của Oracle như sau:
Câu lệnh tạo bảng CUSTOMERDEMO trong Oracle
Các bạn dùng SQL command line hoặc mở Công cụ như SQL Navigator, Oralce SQL Developer để tạo bảng CUSTOMERDEMO
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
create table CUSTOMERDEMO ( CustomerCode varchar2(20) PRIMARY KEY, CustomerName NVARCHAR2(100), CustomerPhone varchar2(30), CustomerEmail varchar2(50), CustomerAddress NVARCHAR2(300), CustomerDate Date ); Insert into CUSTOMERDEMO Values('CUS0000001','Nguyen Van A','091231231','[email protected]','Ha noi',(SYSdate - round( dbms_random.value(18,30),0) *365)); Insert into CUSTOMERDEMO Values('CUS0000002','Tran Van B','091231231','[email protected]','Ha nam',(SYSdate - round( dbms_random.value(18,30),0) *365)); Insert into CUSTOMERDEMO Values('CUS0000003','Do Van C','091231231','[email protected]','Ha Long',(SYSdate - round( dbms_random.value(18,30),0) *365)); select * from CUSTOMERDEMO; |
Đoạn code (SYSdate – round( dbms_random.value(18,30),0) *365) dùng để tạo ngày sinh ngẫu nhiên trong khoảng 18 tới 30 tuổi Oracle. Trong đó hàm SYSDATE lấy ngày giờ hệ thống, hàm Round làm tròn số và hàm dbms_random.value(18,30) dùng để sinh số ngẫu nhiên từ 18 tới 30.
Để truy cập tới bảng CUSTOMERDEMO khi sử dụng .NET Framework Data Provider dành cho Oracle trong ADO.NET chúng ta cần tham chiếu tới thư viện System.Data.OracleClient được cung cấp sẵn trong thư viện .Net Framework. Chúng ta tạo một Project Window Console trong Visual Studio để thực hiện việc sử dụng ADO.NET kết nối tới cơ sở dữ liệu Oracle, add tham chiếu tới không gian tên System.Data.OracleClient, nếu không thấy thư viện này hãy kiểm tra lại phiên bản .Net Framework.
Chú ý: Hiện nay có rất nhiều cách để kết nối tới cơ sở dữ liệu oracle khi sử dụng ngôn ngữ lập trình C#. Cách kết nối System.Data.OracleClient do Microsoft phát triển thường chỉ dành cho project thử nghiệm hoặc các công cụ tiện ích. Khi thực hiện các dự án sản phẩm lớn bạn không nên sử dụng bởi từ nhiều năm trước Microsoft cũng đã không hỗ trợ thêm và khuyến cáo không sử dụng cho dự án phát triển. Khi sử dụng bạn có thể nhận được thông tin khuyến cáo như sau “The types in System.Data.OracleClient are deprecated. The types remain supported in the current version of.NET Framework but will be removed in a future release. Microsoft recommends that you use a third-party Oracle provider.” và khi code sử dụng các đối tượng trong Visual Studio bạn nhé nhận được thông báo ‘System.Data.OracleClient.OracleCollection is obsolete’ : “OracleConnection has been deprecated. http://go.microsoft.com/fwlink/?LinkID=144260“
1. Nhận kết quả truy vấn bảng bằng cách sử dụng đối tượng OracleDataAdapter
Dưới đây là code nhận kết quả trả về khi truy vấn bảng CUSTOMERDEMO bằng việc nhận kết quả trả về bằng cách sử dụng đối tượng OracleDataAdapter trong ADO.NET để lẫy dữ liệu trong cơ sở dữ liệu và trả về DataTable trong bộ nhớ như sau :
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
// hàm Kết nối tới cơ sở dữ liệu dùng OracleDataAdapter static DataTable GetDataUsingOracleDataAdapter() { // Chuỗi kết nối xác định vị trí cài đặt cơ sở dữ liệu string chuoiKetNoi = @"Data [email protected]:@BasePort/@BaseName;User [email protected];[email protected]"; //Khai báo 1 đối tượng DataTable để lưu trữ dữ liệu lấy từ cơ sở dữ liệu, rồi lưu trên bộ nhớ (RAM) DataTable customerTable = new DataTable(); //Thực sự mở kết nối tới cơ sở dữ liệu OracleConnection conn = new OracleConnection(chuoiKetNoi); try { //Mở kết nối tới base conn.Open(); //Khai báo một đối tượng OracleCommand để thực thi câu lệnh dựa trên kết nối đã mở OracleCommand comm = new OracleCommand(); comm.Connection = conn; // Khai báo câu lệnh cần thực hiện comm.CommandType = CommandType.Text; comm.CommandText = "select CustomerCode, CustomerName,CustomerPhone,CustomerEmail, CustomerAddress, CustomerDate from CustomerDemo"; //comm.CommandText = "select CustomerCode,CustomerName,CustomerPhone,CustomerEmail, CustomerAddress, CustomerDate from MitBeoCustomer;"; //Khai báo 1 đối tượng để nhận thông tin trả vể từ đối tượng Command OracleDataAdapter adapter = new OracleDataAdapter(comm); //Đổ dữ liệu nhận được từ cơ sở dữ liệu cho đối tượng DataTable trong bộ nhớ (RAM) adapter.Fill(customerTable); } catch (Exception ex) { throw ex; } finally { // Đóng kết nối sau khi thao tác if (conn.State == ConnectionState.Open) { conn.Close(); } } return customerTable; |
Result
Sử dụng hàm hiện thi kết quả với dữ liệu đầu vào là một DataTable
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
static void Main(string[] args) { HienThiDataTable(GetDataUsingOracleDataAdapter()); Console.ReadLine(); } static void HienThiDataTable(DataTable pResult) { foreach (DataRow item in pResult.Rows) { Console.WriteLine(string.Join(",", item.ItemArray.Select(o => o.ToString()))); } } |
Chúng ta nhận được kết quả như sau :
2. Nhận kết quả truy vấn bảng bằng cách sử dụng đối tương OracleDataReader
Dưới đây là code nhận kết quả trả về khi truy vấn bảng CUSTOMERDEMO bằng việc nhận kết quả trả về bằng cách sử dụng đối tượng OracleDataReader trong provider System.Data.OracleClient của ADO.NET chỉ đọc, chỉ chuyển tiếp như sau :
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
// Định nghĩa một hàm đọc dữ liệu từ bảng trong Oracle sử dụng OracleDataReader static List GetDataUsingOracleDataReader() { // Chuỗi kết nối xác định vị trí cài đặt cơ sở dữ liệu string chuoiKetNoi = @"Data [email protected]:@BasePort/@BaseName;User [email protected];[email protected]"; //Khai báo một list các đối tượng MitBeoCustomer để nhận kết quả trả về // Đối tượng C# có các thuộc tính tương ứng với các cột trong bảng cơ sở dữ liệu List customerList = new List(); //Thực sự mở kết nối tới cơ sở dữ liệu OracleConnection conn = new OracleConnection(chuoiKetNoi); try { //Mở kết nối tới base conn.Open(); //Khai báo một đối tượng Command để thực thi câu lệnh dựa trên kết nối đã mở OracleCommand comm = new OracleCommand(); comm.Connection = conn; // Khai báo câu lệnh cần thực hiện comm.CommandType = CommandType.Text; comm.CommandText = "select CustomerCode, CustomerName,CustomerPhone,CustomerEmail, CustomerAddress, CustomerDate from CustomerDemo"; //Sử dụng phương thức ExecuteReader của đối tượng Command để nhận về dữ liệu OracleDataReader reader = comm.ExecuteReader(); // đọc lần lượt các dòng, chỉ tiến while (reader.Read()) { customerList.Add(new MitBeoCustomerClass() { CustomerCode = reader.GetString(0), CustomerName = reader.GetString(1), CustomerPhone = reader.GetString(2), CustomerEmail = reader.GetString(3), CustomerAddress = reader.GetString(4), CustomerDate = reader.GetDateTime(5) }); } } catch (Exception ex) { throw ex; } finally { // Đóng kết nối sau khi thao tác if (conn.State == ConnectionState.Open) { conn.Close(); } } return customerList; } |
Result
Để nhận kết quả từ bảng CUSTOMERDEMO từ OracleDataReader ta cần khai báo thêm 1 lớp MitBeoCustomerClass trong ngôn ngữ C# mà có các thuộc tính của nó tương ứng với các cột dữ liệu trong bảng CUSTOMERDEMO như sau :
1 2 3 4 5 6 7 8 9 |
public class MitBeoCustomerClass { public string CustomerCode { get; set; } public string CustomerName { get; set; } public string CustomerPhone { get; set; } public string CustomerEmail { get; set; } public string CustomerAddress { get; set; } public DateTime CustomerDate { get; set; } } |
Sử dụng hàm hiển thị kết quả với dữ liệu đầu vào là một danh sách các lớp MitBeoCustomerClass
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
static void Main(string[] args) { HienThiList(GetDataUsingOracleDataReader()); Console.ReadLine(); } static void HienThiList(List pResult) { foreach (MitBeoCustomerClass item in pResult) { Console.WriteLine(string.Join(",", item.CustomerCode, item.CustomerName, item.CustomerPhone, item.CustomerEmail, item.CustomerAddress, item.CustomerDate.ToString())); } } |
Chúng ta nhận được kết quả như sau :
3. Sử dụng OracleDataAdapter hay OracleDataReader
Nếu bạn cần phát triển các tính năng chỉ cần đọc dữ liệu từ bảng, bạn nên dùng OracleDataReader, vì khi sử dụng OracleDataReader trong việc xử lý chỉ đọc dữ liệu sẽ khiến cho tốc độ xử lý nhanh hơn rất nhiều với OracleDataAdapter. Dưới đây là đoạn code sử dụng lớp Stopwatch để so sánh thời gian chương trình thực thi của OracleDataAdapter và OracleDataReader trong ADO.NET để minh họa cho nhận xét trên:
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
// Hàm thực thi so sánh OracleDataReader và OracleDataAdapter static List CompareOracleDataReaderVsOracleDataAdapter() { // Chuỗi kết nối xác định vị trí cài đặt cơ sở dữ liệu string chuoiKetNoi = @"Data Source=123.30.246.137:1521/hddtdb;User Id=invtest_mienbac;Password=invtest_mienbac"; //Khai báo một list các đối tượng MitBeoCustomer để nhận kết quả trả về // Đối tượng C# có các thuộc tính tương ứng với các cột trong bảng cơ sở dữ liệu List customerList = new List(); //Khai báo 1 đối tượng DataTable để lưu trữ dữ liệu lấy từ cơ sở dữ liệu, rồi lưu trên bộ nhớ (RAM) DataTable customerTable = new DataTable(); //Thực sự mở kết nối tới cơ sở dữ liệu OracleConnection conn = new OracleConnection(chuoiKetNoi); try { //Mở kết nối tới base conn.Open(); // Khai báo đối tượng Stopwatch Stopwatch swObj = new Stopwatch(); swObj.Start(); //Khai báo một đối tượng Command để thực thi câu lệnh dựa trên kết nối đã mở OracleCommand comm = new OracleCommand(); comm.Connection = conn; string sqlQuery = "select CustomerCode, CustomerName,CustomerPhone,CustomerEmail, CustomerAddress, CustomerDate from CustomerDemo"; // Khai báo câu lệnh cần thực hiện comm.CommandType = CommandType.Text; comm.CommandText = sqlQuery; //Sử dụng phương thức ExecuteReader của đối tượng Command để nhận về dữ liệu OracleDataReader reader = comm.ExecuteReader(); // đọc lần lượt các dòng, chỉ tiến while (reader.Read()) { customerList.Add(new MitBeoCustomerClass() { CustomerCode = reader.GetString(0), CustomerName = reader.GetString(1), CustomerPhone = reader.GetString(2), CustomerEmail = reader.GetString(3), CustomerAddress = reader.GetString(4), CustomerDate = reader.GetDateTime(5) }); } // Thời gian kết thúc đo sử dụng OracleDataReader swObj.Stop(); //Tổng thời gian thực hiện sử dụng OracleDataReader Console.WriteLine("Total time with using OracleDataReader:=" + swObj.ElapsedTicks); //Thời gian bắt đầu đo sử dụng OracleDataAdapter swObj.Restart(); //Khai báo một đối tượng OracleCommand để thực thi câu lệnh dựa trên kết nối đã mở OracleCommand commAdapter = new OracleCommand(); commAdapter.Connection = conn; // Khai báo câu lệnh cần thực hiện commAdapter.CommandType = CommandType.Text; commAdapter.CommandText = sqlQuery; //comm.CommandText = "select CustomerCode,CustomerName,CustomerPhone,CustomerEmail, CustomerAddress, CustomerDate from MitBeoCustomer;"; //Khai báo 1 đối tượng để nhận thông tin trả vể từ đối tượng Command OracleDataAdapter adapter = new OracleDataAdapter(commAdapter); //Đổ dữ liệu nhận được từ cơ sở dữ liệu cho đối tượng DataTable trong bộ nhớ (RAM) adapter.Fill(customerTable); // Thời gian kết thúc đo sử dụng OracleDataAdapter swObj.Stop(); //Tổng thời gian thực hiện sử dụng OracleDataAdapter Console.WriteLine("Total time with using OracleDataAdapter:=" + swObj.ElapsedTicks); } catch (Exception ex) { throw ex; } finally { // Đóng kết nối sau khi thao tác if (conn.State == ConnectionState.Open) { conn.Close(); } } return customerList; } |
Result
Các bạn có thể Download code : Tại đây