天天看點

ADO.NET與ORM的比較(1):ADO.NET實作CRUD

說明:個人感覺在Java領域大型開發都離不了ORM的身影,所謂的SSH就是Spring+Struts+Hibernate,除了在學習基礎知識的時候被告知可以使用JDBC操作資料庫之外,大量的書籍中都是講述使用Hibernate這個ORM工具來操作資料。在.NET中操作資料庫的方式有多種,除了最直接的方式就是使用ADO.NET之外,還可以使用NHibernate這個Hibernate在.NET中的實作ORM,如果你對第三方的ORM持懷疑态度,你還可以使用來自微軟的實作、根正苗紅的Linq或者EntityFramework。

大部分從早期就開始使用.NET開發的程式員可能對ADO.NET有種迷戀,使用ADO.NET可以充分将我們早期的SQL知識發揮得淋漓盡緻,并且出于對性能的考慮,有些人對.NET中的ORM還保持一種觀望态度,包括我自己也是這種态度。不過即使在實際開發中不用,并不代表我們不能去了解和比較這些技術,任何事物的出現和消亡總有其原因的,我們可以了解它們的優點和長處。是以本人抽出了幾個周末的時間分别用ADO.NET、NHibernate、Linq和EntityFramework來實作對資料庫單表資料的建立、讀取、更新和删除操作,也就是所謂的CRUD(C:Create/R:Read/U:Update/D:Delete)。

通過實作相同功能的比較,大家自己判斷那種方式更适合自己。需要說明的是,如果在VS2008中使用EntityFramework就需要安裝VS2008SP1。

在開始示範之前先準備好資料,在本系列中所使用的資料庫是SQL Server2005,建立和初始化資料庫資料的代碼如下:

/****** 對象:    Table [dbo].[UserInfo]        腳本日期: 03/08/2010 12:20:11 ******/ 

SET ANSI_NULLS ON 

GO 

SET QUOTED_IDENTIFIER ON 

IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[UserInfo]') AND type in(N'U')) 

BEGIN 

CREATE TABLE [dbo].[UserInfo]( 

  [UserID] [int] IDENTITY(1,1) NOT NULL, 

  [UserName] [varchar](20) COLLATE Chinese_PRC_CI_AS NOT NULL, 

  [RealName] [nvarchar](8) COLLATE Chinese_PRC_CI_AS NOT NULL, 

  [Age] [tinyint] NOT NULL, 

  [Sex] [bit] NOT NULL, 

  [Mobile] [char](11) COLLATE Chinese_PRC_CI_AS NULL, 

  [Phone] [char](11) COLLATE Chinese_PRC_CI_AS NULL, 

  [Email] [varchar](50) COLLATE Chinese_PRC_CI_AS NOT NULL, 

CONSTRAINT [PK_UserInfo] PRIMARY KEY CLUSTERED    

  [UserID] ASC 

)WITH (IGNORE_DUP_KEY = OFF) 

END 

IF NOT EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[UserInfo]') AND name= N'IX_UserName') 

CREATE UNIQUE NONCLUSTERED INDEX [IX_UserName] ON [dbo].[UserInfo]    

  [UserName] ASC 

)WITH (IGNORE_DUP_KEY = ON) 

GO

下面開始示範如何使用ADO.NET實作CRUD功能。

一、配置

建立一個控制台或者類庫項目,并且添加一個app.config配置檔案,在此檔案中添加資料庫配置資訊,如下:

<connectionStrings> 

  <add name="Conn" connectionString="Data Source=zhou;Initial Catalog=AspNetStudy;User ID=sa;Password=jerry" /> 

</connectionStrings>

二、建立實體類

using System; 

using System.Collections.Generic; 

using System.Text; 

namespace ADODoNETDemo 

        public class UserInfo 

        { 

                /// <summary> 

                /// 使用者編号 

                /// </summary> 

                public int UserId { get; set; } 

                /// 使用者名 

                public string UserName { get; set; } 

                /// 真實姓名 

                public string RealName { get; set; } 

                /// 年齡 

                public byte Age { get; set; } 

                /// 性别 

                public bool Sex { get; set; } 

                /// 電子郵件 

                public string Email { get; set; } 

                /// 手機号 

                public string Mobile { get; set; } 

                /// 電話 

                public string Phone { get; set; } 

        } 

}

三、建立資料庫通路通用類

說明:下面的這個資料庫通用類适用于通路資料庫中任意表,不管是基于文本方式SQL、參數化SQL語句或者存儲過程都可以。

很郁悶受篇幅限制,這裡将代碼放在附件裡。

四、建立CRUD類

對資料庫實作增删改查功能的類的代碼如下:

using System.Linq; 

using System.Data.SqlClient; 

using System.Data; 

        /// <summary> 

        /// 用ADO.NET實作CRUD功能 

        /// </summary> 

        public class ADODotNetCRUD 

                /// 統計使用者總數 

                /// <returns></returns> 

                public int Count() 

                { 

                        string sql = "select count(1) from UserInfo"; 

                        SqlDbHelper db = new SqlDbHelper(); 

                        return int.Parse(db.ExecuteScalar(sql).ToString()); 

                } 

                /// 建立使用者 

                /// <param name="info">使用者實體</param> 

                public bool Create(UserInfo info) 

                        string sql = "insert UserInfo(UserName,RealName,Age,Sex,Mobile,Email,Phone)values(@UserName,@RealName,@Age,@Sex,@Mobile,@Email,@Phone)"; 

                        SqlParameter[] paramters = new SqlParameter[]{ 

                                new SqlParameter("@UserName",info.UserName), 

                                new SqlParameter("@RealName",info.RealName), 

                                new SqlParameter("@Age",info.Age), 

                                new SqlParameter("@Sex",info.Sex), 

                                new SqlParameter("@Mobile",info.Mobile), 

                                new SqlParameter("@Email",info.Email), 

                                new SqlParameter("@Phone",info.Phone), 

                        }; 

                        return db.ExecuteNonQuery(sql, CommandType.Text, paramters) > 0; 

                /// 讀取使用者資訊 

                /// <param name="userId">使用者編号</param> 

                public UserInfo Read(int userId) 

                        string sql = "select * from UserInfo Where UserId="+userId; 

                        DataTable data = db.ExecuteDataTable(sql); 

                        if (data.Rows.Count > 0) 

                        { 

                                DataRow row = data.Rows[0]; 

                                UserInfo info = new UserInfo() 

                                { 

                                        UserId=int.Parse(row["UserId"].ToString()), 

                                        UserName=row["UserName"].ToString(), 

                                        Age=byte.Parse(row["Age"].ToString()), 

                                        Email=row["Email"].ToString(), 

                                        Mobile=row["Mobile"].ToString(), 

                                        Phone=row["Phone"].ToString(), 

                                        RealName=row["RealName"].ToString(), 

                                        Sex=bool.Parse(row["Sex"].ToString()) 

                                }; 

                                return info; 

                        } 

                        else 

                                return null; 

                /// 更新使用者資訊 

                public bool Update(UserInfo info) 

                        string sql = "update UserInfo set UserName=@UserName,RealName=@RealName,Age=@Age,Sex=@Sex,Mobile=@Mobile,Email=@Email,Phone=@Phone where UserID=@UserID"; 

                                new SqlParameter("@UserID",info.UserId), 

                /// 删除使用者 

                public bool Delete(int userId) 

                        string sql = "delete from UserInfo where UserId=" + userId; 

                        return db.ExecuteNonQuery(sql) > 0; 

                /// 擷取使用者表中編号最大的使用者 

                public int GetMaxUserId() 

                        string sql = "select max(userId) from UserInfo"; 

五、NUnit單元測試代碼

在進行單元測試時沒有使用VS自帶的單元測試工具,仍是我平常用慣了的NUnit,下面是代碼:

很遺憾,受篇幅限制,這裡代碼也以附件形式提供。

六、點評

在使用ADO.NET操作資料庫時個人覺得有如下優點,可以随心所欲地使用熟知的SQL語句甚至是存儲過程,在使用統計、分組功能時感覺尤其強烈,當然前提是你的SQL基礎要相當好,此外它是其它幾種ORM的基礎,其它幾種ORM都是在底層使用ADO.NET實作與資料庫的互動的,是以在效率上來說它也要高一些。它的缺點是需要自己寫操作資料的語句并且需要自己編寫資料庫記錄到實體的映射轉換代碼,一旦表的結構發生變動,就需要修改實體類和映射轉換代碼。

本文轉自周金橋51CTO部落格,原文連結: http://blog.51cto.com/zhoufoxcn/283952,如需轉載請自行聯系原作者