程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> ADO.NET與ORM的比較(3) Linq to SQL實現CRUD

ADO.NET與ORM的比較(3) Linq to SQL實現CRUD

編輯:關於.NET

說明:個人感覺在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。

語言集成查詢 (LINQ) 是 Visual Studio 2008 中的一組功能,可為 C# 和 Visual Basic 語言語法提供強大的查詢功能。LINQ 引入了標准的、易於學習的 查詢和更新數據模式,可以對其技術進行擴展以支持幾乎任何類型的數據存儲。 Visual Studio 2008 包含 LINQ 提供程序的程序集,這些程序集支持將 LINQ 與 .NET Framework 集合、SQL Server 數據庫、ADO.NET 數據集和 XML 文檔一 起使用。

在本篇講述利用Linq實現對數據庫的CRUD功能,也就是Linq to SQL,需要說 明的是Linq to SQL只支持SQL Server數據庫,Linq to SQL只是Linq的一部分功 能。

用Linq to SQL來操作數據庫確實比使用NHibernate在操作上要方便得多,通 過下面的操作讀者也會體會得到,畢竟這個是微軟官方的東東,微微支持的力度 自然要大些。

一、准備

首先,向項目中添加Linq To SQL的類,如下圖所示:

在名稱一欄中填寫較友好的名字之後,然後項目中就會增加一個後綴為dbml 的文件,雙擊這個文件就會進入設計視圖,如下圖所示:

在服務器資源管理中找到相應的數據庫連接,依次點開之後就可以將數據庫 中的表拖到dbml設計器上。如果讀者界面上沒有服務器資源管理器可以使用 CTRL+ALT+S組合鍵將其調出來。如果沒有數據庫連接,可以按照下面的步驟進行 ,在服務器資源管理器中的“數據連接”—— “添加連接”,出現如下界面:

在上面的界面中依次填寫好數據庫、用戶名和密碼及要連接的庫名之 後,點擊確定,這樣在服務器資源管理器中就增加了一個數據庫連接,展開之後 如下圖所示:

拖拽一個表到dbml上就會自動生成這個表的實體類,如下圖所示:

也許有人會思考這個類的定義在哪裡,可以告訴你的是這個類的定義 在這個dbml文件對應的cs文件中(dbml文件名.designer.cs這種形式),如下圖 所示:

有些這些之後我們就可以動手編碼實現對數據庫進行CRUD操作了。

二 、編碼

由於在dbml文件中已經存在了DataContext和UserInfo表對應的 UserInfo實體類,所以我們僅僅需要編寫對數據庫操作的類就可以了。編寫的代 碼如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Data.Linq;
using System.Configuration;

namespace LinqDemo
{
          /// <summary>
          /// 說明:這個類是為了演示.NET中的Linq to SQL 的用法
          /// 作者:周公(周金橋)
          /// 日期:2010-03-01
          /// </summary>
          public class LinqCRUD
          {
                  /// <summary>
                  /// 統計用戶總數
                  /// </summary>
                  ///  <returns></returns>
                  public int Count()
                  {
方法一#region 方法一
                          //使用  SqlConnection來實例化DataContext對象
                          SqlConnection  connection = new SqlConnection (ConfigurationManager.ConnectionStrings ["LinqDemo.Properties.Settings.AspNetStudyConnectionString"].Connectio nString);
                          DataContext  context = new DataContext(connection);
                          IEnumerable<int> collection =  context.ExecuteQuery<int>("select count(1) from  UserInfo");
                          int count =  collection.ElementAt<int>(0);
                          return  count;
                          #endregion

方法二#region 方法二
                          //UserInfoDataClassesDataContext context = new  UserInfoDataClassesDataContext();
                          ////return  context.UserInfo.Count<UserInfo>(item => item.Age >  23);//帶條件統計
                          //return  context.UserInfo.Count<UserInfo>();
                          #endregion
                  }
                  /// <summary>
                  /// 創建用戶
                  /// </summary>
                  /// <param name="info">用 戶實體</param>
                  ///  <returns></returns>
                  public void Create(UserInfo  info)
                  {
                          UserInfoDataClassesDataContext context = new  UserInfoDataClassesDataContext();
                          context.UserInfo.InsertOnSubmit(info);
                          context.SubmitChanges();
                  }
                  /// <summary>
                  /// 讀取用戶信息
                  /// </summary>
                  /// <param name="userId"> 用戶編號</param>
                  ///  <returns></returns>
                  public UserInfo Read(int  userId)
                  {
                          UserInfoDataClassesDataContext context = new  UserInfoDataClassesDataContext();
                          context.Log =  Console.Out;
                          var query =  from item in context.UserInfo
                                                   where item.UserID == userId
                                                   select item;
                          return  query.First<UserInfo>();
                  }
                  /// <summary>
                  /// 更新用戶信息
                  /// </summary>
                  /// <param name="info">用 戶實體</param>
                  ///  <returns></returns>
                  public void Update(UserInfo  info)
                  {
                          UserInfoDataClassesDataContext context = new  UserInfoDataClassesDataContext();
                          UserInfo ui =  context.UserInfo.First<UserInfo>(item => item.UserID ==  info.UserID);
                          ui.Age =  info.Age;
                          ui.Email =  info.Email;
                          ui.Mobile =  info.Mobile;
                          ui.Phone =  info.Phone;
                          ui.RealName =  info.RealName;
                          ui.Sex =  info.Sex;
                          ui.UserName =  info.UserName;
                          context.SubmitChanges();
                  }
                  /// <summary>
                  /// 刪除用戶
                  /// </summary>
                  /// <param name="userId"> 用戶編號</param>
                  ///  <returns></returns>
                  public void Delete(int  userId)
                  {
方法一#region 方法一
                          //UserInfoDataClassesDataContext context = new  UserInfoDataClassesDataContext();
                          //context.ExecuteCommand("delete from UserInfo where UserId=" +  userId);
                          #endregion
方法二#region 方法二
                          UserInfoDataClassesDataContext context = new  UserInfoDataClassesDataContext();
                          UserInfo ui =  context.UserInfo.First<UserInfo>(item => item.UserID ==  userId);
                          context.UserInfo.DeleteOnSubmit(ui);
                          context.SubmitChanges();
                          #endregion
                  }

                  /// <summary>
                  /// 刪除用戶
                  /// </summary>
                  /// <param name="userId"> 用戶實體</param>
                  ///  <returns></returns>
                  public void Delete(UserInfo  info)
                  {
                          UserInfoDataClassesDataContext context = new  UserInfoDataClassesDataContext();
                          var userList =  from Users
                                                              in  context.UserInfo
                                                              where  Users.UserID == info.UserID    
                                                              select  Users;
                          foreach (var  user in userList)
                          {
                                  context.UserInfo.DeleteOnSubmit(user);
                          }
                          //context.UserInfo.DeleteOnSubmit(userList.First<UserInfo> ());
                          //注意下面的寫法 是錯誤的
                         //  context.UserInfo.DeleteOnSubmit(info);
                          context.SubmitChanges();
                  }

                  /// <summary>
                  /// 獲取用戶表中編號最大的用戶
                  /// </summary>
                  ///  <returns></returns>
                  public int GetMaxUserId()
                  {
                          UserInfoDataClassesDataContext context = new  UserInfoDataClassesDataContext();
                          int  userId=context.UserInfo.Max<UserInfo>(item =>  item.UserID);
                          return  userId;
                  }
          }
}

說明,在上面的代碼中每個方法的第一句都是實例化一個叫 UserInfoDataClassesDataContext的類,這個類我們並沒有編寫,但是奇怪的是 上面的代碼居然能編譯通過,這是為什麼呢?原來秘密還是在那個dbml文件中, 這個類在dbml的設計文件中的定義如下:

[System.Data.Linq.Mapping.DatabaseAttribute (Name="AspNetStudy")]
public partial class UserInfoDataClassesDataContext :  System.Data.Linq.DataContext
{
//.....省略其它代碼
}

可以看出UserInfoDataClassesDataContext是繼承DataContext的,這個 DataContext在MSDN中的定義為:

DataContext 是通過數據庫連接映射的所有實體的源。它會跟蹤您對所有檢 索到的實體所做的更改,並且保留一個“標識緩存”,該緩存確保使用同一對象 實例表示多次檢索到的實體。

也就是我們用DataContext來與數據庫進行交互,DataContext會根據上下文 環境來決定如何與數據庫交互,正因為如此,所以我們用Linq to SQL的代碼才 如此簡單!

三、單元測試代碼

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using LinqDemo;

namespace NUnitTest
{
          [TestFixture]
          public class LinqTest
          {
                  private LinqCRUD instance =  null;
                  [SetUp]
                  public void Initialize()
                  {
                          instance = new  LinqCRUD();
                  }
                  [Test]
                  /// <summary>
                  /// 統計用戶總數
                  /// </summary>
                  ///  <returns></returns>
                  public void Count()
                  {
                          Assert.Greater (instance.Count(), 0);
                  }
                  [Test]
                  /// <summary>
                  /// 創建用戶
                  /// </summary>
                  /// <param name="info">用 戶實體</param>
                  ///  <returns></returns>
                  public void Create()
                  {
                          UserInfo info =  new UserInfo()
                          {
                                  Age = 12,
                                  Email = "[email protected]",
                                  Mobile = "13812345678",
                                  Phone = "01012345678",
                                  RealName = "測試" + DateTime.Now.Millisecond.ToString(),
                                  Sex = true,
                                  UserName = "zhoufoxcn" + DateTime.Now.Millisecond.ToString()
                          };
                          instance.Create (info);
                  }
                  [Test]
                  /// <summary>
                  /// 讀取用戶信息
                  /// </summary>
                  /// <param name="userId"> 用戶編號</param>
                  ///  <returns></returns>
                  public void Read()
                  {
                          UserInfo info =  instance.Read(1);
                          Assert.NotNull (info);
                  }
                  [Test]
                  /// <summary>
                  /// 更新用戶信息
                  /// </summary>
                  /// <param name="info">用 戶實體</param>
                  ///  <returns></returns>
                  public void Update()
                  {
                          UserInfo info =  instance.Read(1);
                          info.RealName =  "測試" + DateTime.Now.Millisecond.ToString();
                          instance.Update (info);
                  }
                  [Test]
                  /// <summary>
                  /// 刪除用戶
                  /// </summary>
                  /// <param name="userId"> 用戶編號</param>
                  ///  <returns></returns>
                  public void DeleteByID()
                  {
                          int userId =  instance.GetMaxUserId();
                          instance.Delete (userId);
                  }

                  [Test]
                  /// <summary>
                  /// 刪除用戶
                  /// </summary>
                  /// <param name="userId"> 用戶實體</param>
                  ///  <returns></returns>
                  public void Delete()
                  {
                          int userId =  instance.GetMaxUserId();
                          UserInfo info =  instance.Read(userId);
                          //Console.WriteLine("MaxUserId=" + userId);
                          instance.Delete (info);
                  }
          }
}

上面的代碼在NUnit2.5.3中測試通過。

四、總結

NHibernate 與ADO.NET相比開發更簡單,應對數據庫的變化更靈活,而Linq to SQL比NHibernate更方便應對數據庫變化,開發效率也高,使用Linq to SQL 後我們僅需要編寫一個類就足夠了,比較遺憾的是Linq to SQL只支持SQL Server,所以很多人都在使用Entity Framework這個ORM框架了。

出處http://zhoufoxcn.blog.51cto.com/792419/293966

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved