一、前言
任何一個應用程序都離不開數據的存儲,數據可以在內存中存儲,但只能在程序運行時存取,無法持久保存。
數據還可以在磁盤中以文件的形式存儲,但文件的管理和查找又十分煩瑣無法勝任大數量的存儲。
將數據存儲到數據庫中是在應用程序中持久存儲數據的常用方式。
在 C# 語言中提供了 ADO.NET 組件來實現連接數據庫以及操作數據庫中數據的功能。
二、使用ADO.NET操作數據庫
在 C#語言中 ADO.NET 是在 ADO 的基礎上發展起來的,ADO (Active Data Object) 是一個 COM 組件類庫,用於訪問數據庫,而 ADO.NET 是在 .NET 平台上訪問數據庫的組件。
ADO.NET 是以 ODBC (Open Database Connectivity) 技術的方式來訪問數據庫的一種技術。下面我們通過winform窗體應用來使用ADO.NET。
1.新建winform程序,放置一個按鈕,用來測試數據庫連接。
2.在forms1.cs里引用using System.Data.SqlClient;並寫一個連接sql的方法
static SqlConnection Conn() { //編寫數據庫連接串 string connStr = "Data source=.;Initial Catalog=test;User ID=sa;Password=sa123"; //創建SqlConnection的實例 SqlConnection conn = null; try { conn = new SqlConnection(connStr); //打開數據庫連接 conn.Open(); MessageBox.Show("數據庫連接成功!"); } catch (Exception ex) { conn.Close(); MessageBox.Show("數據庫連接失敗!" + ex.Message); } finally { if (conn != null) { //關閉數據庫連接 conn.Close(); } } return conn; }
3.新建全局變量 conn,並綁定按鈕點擊事件,這樣就不用每次操作都要連接一下數據庫:
public SqlConnection conn; private void test_conn_Click(object sender, EventArgs e) { conn = Conn(); }
4.運行程序,點擊按鈕,如果連接成功會提示連接成功,如果失敗提示失敗原因。
5.數據庫連接成功,下面開始插入數據。新建表t_product,定義三個字段,id,name,stock,id設為主鍵並自增。
6.放置一個添加按鈕,並綁定點擊事件。
private void add_Click(object sender, EventArgs e) { if (conn!=null) { try { conn.Open(); string sql = "insert into t_product(Name,Stock) values('{0}',{1})"; //填充SQL語句 sql = string.Format(sql, "商品1", 53); //創建SqlCommand對象 SqlCommand cmd = new SqlCommand(sql, conn); //執行SQL語句 int returnvalue = cmd.ExecuteNonQuery(); //判斷SQL語句是否執行成功 if (returnvalue != -1) { MessageBox.Show("插入數據成功!"); } } catch (Exception ex) { MessageBox.Show("插入數據失敗!" + ex.Message); } finally { if (conn != null) { //關閉數據庫連接 conn.Close(); } } } else { MessageBox.Show("請檢查數據庫連接!"); } }
7.多次點擊添加按鈕,提示添加成功,數據庫查看數據。
8.插入數據沒問題,下面開始查詢數據,頁面放置查詢按鈕,用來查詢數據,一個listview控件,用來顯示信息。
9.綁定查詢事件,點擊查詢按鈕,listview顯示數據庫的數據:
private void query_all_Click(object sender, EventArgs e) { if (conn != null) { try { string sql = "select Name from t_product"; //創建 SqlDataAdapter 類的對象 SqlDataAdapter sda = new SqlDataAdapter(sql, conn); //創建 DataTable 類的對象 DataTable dt = new DataTable(); //使用 SqlDataAdapter 對象 sda 將查詢結果填充到 DataSet 對象 dt 中 sda.Fill(dt); //設置 ListBox 控件的數據源(DataSource)屬性 pro_list.DataSource = dt; //在 ListBox 控件中顯示 name 列的值 pro_list.DisplayMember = dt.Columns[0].ToString(); } catch (Exception ex) { MessageBox.Show("插入數據失敗!" + ex.Message); } finally { if (conn != null) { //關閉數據庫連接 conn.Close(); } } } else { MessageBox.Show("請檢查數據庫連接!"); } }
三、什么是ORM
ORM(Object Relational Mapping)是對象關系映射。它的實質就是將關系數據(庫)中的業務數據用對象的形式表示出來,並通過面向對象(Object-Oriented)的方式將這些對象組織起來,實現系統業務邏輯的過程。在ORM過程中最重要的概念是映射(Mapping),通過這種映射可以使業務對象與數據庫分離。從面向對象來說,數據庫不應該和業務邏輯綁定到一起,ORM則起到這樣的分離作用,使數據庫層透明,開發人員真正的面向對象 。
ORM是隨着面向對象的軟件開發方法發展而產生的。面向對象的開發方法是當今企業級應用開發環境中的主流開發方法,關系數據庫是企業級應用環境中永久存放數據的主流數據存儲系統。對象和關系數據是業務實體的兩種表現形式,業務實體在內存中表現為對象,在數據庫中表現為關系數據。內存中的對象之間存在關聯和繼承關系,而在數據庫中,關系數據無法直接表達多對多關聯和繼承關系。因此,對象-關系映射(ORM)系統一般以中間件的形式存在,主要實現程序對象到關系數據庫數據的映射。
一般的ORM包括以下四部分:
一個對持久類對象進行CRUD操作的API;
一個語言或API用來規定與類和類屬性相關的查詢;
一個規定mapping metadata的工具;
一種技術可以讓ORM的實現同事務對象一起進行dirty checking, lazy association fetching以及其他的優化操作。
三、使用Entity Framework
1.安裝EF
2.創建實體類User
namespace WindowsFormsApp1 { [Table("t_user")]//設置表名 public class User { [Key] public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } } }
3.為實體類創建一個數據庫上下文類DbContext:
using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Text; using System.Threading.Tasks; namespace WindowsFormsApp1 { class UserDbContext: System.Data.Entity.DbContext { /// <summary> /// /// 數據庫上下文類中存在了一個構造函數,一個用來操作的數據庫的上下文,被DbSet定義的user。 ///構造函數的作用是定義一個連接數據庫的字符串"Conn"。 /// </summary> public UserDbContext() : base("Conn") { } /// <summary> /// 被DbSet定義的user就是我們用來操作數據庫的上下文,里面存在了常用的Add,Delete,Save等增刪改查方法。 /// </summary> public DbSet<User> user{ get; set; } } }
4.配置app.config文件,添加<connectionStrings>屬性<add>里面主要存在三個重要配置信息,name為上下文類設置的連接字符串,connectionStrings為連接數據庫信息,providerName定義了連接不同數據庫的類型,這里為sqlserver
<connectionStrings> <add name="Conn" connectionString="server=.;uid=sa;pwd=sa123;database=." providerName="System.Data.SqlClient" /> </connectionStrings>
5.頁面新建一個按鈕,用來操作EF插入數據,並綁定點擊事件。
private void ef_add_Click(object sender, EventArgs e) { try { UserDbContext db = new UserDbContext(); User pd = new User(); pd.Name = "張三"; pd.Age = 11; db.user.Add(pd); db.SaveChanges(); MessageBox.Show("EF插入數據成功!"); } catch (Exception ex) { MessageBox.Show("EF插入數據失敗!" + ex.Message); } }
點擊按鈕提示插入成功。
6.EF查詢有三種方式,所以我們在頁面新建三個按鈕用來查詢數據,分別綁定三個按鈕的點擊事件。
初始數據:

private void ef_query1_Click(object sender, EventArgs e) { try { UserDbContext db = new UserDbContext(); //查詢年齡為11的人,並按照ID倒序排序 var persons = from p in db.user where p.Age == 11 orderby p.Id descending select p; foreach (var p in persons) { user_list.Items.Add(p.Name); } MessageBox.Show("查詢數據成功!"); } catch (Exception ex) { MessageBox.Show("查詢數據失敗!" + ex.Message); } }


private void ef_query3_Click(object sender, EventArgs e) { try { UserDbContext db = new UserDbContext(); var age =11; //查詢年齡為11的人,並按照ID倒序排序 var persons = db.user.SqlQuery($"select * from t_user where Age='{age}' order by id desc"); foreach (var p in persons) { user_list.Items.Add(p.Name); } //不僅如此,EF還支持非實體類型的查詢 //var persons = db.Database.SqlQuery<string>($"select Name from t_user where Age='{age}' order by id desc"); //foreach (var p in persons) //{ // user_list.Items.Add(p); //} MessageBox.Show("查詢數據成功!"); } catch (Exception ex) { MessageBox.Show("查詢數據失敗!" + ex.Message); } }
結果: