程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 一個ORM的實現(附源代碼),orm實現附源代碼

一個ORM的實現(附源代碼),orm實現附源代碼

編輯:C#入門知識

一個ORM的實現(附源代碼),orm實現附源代碼


1  前言

經過一段時間的編寫,終於有出來一個穩定的版本,期間考慮了多種解決方案也偷偷學了下園子裡面大神們的作品。

已經有很多的ORM框架,為什麼要自己實現一個?我的原因是在遇到特殊需求時,可以在ORM中加入特定的代碼。如 :根據數據庫的字段長度和可空性做基本的數據驗證,在ORM中解決數據修改時的同步問題…

本文主要關注的是如何實現ORM方面,其它的大家可以參考以下兩篇文章:

用T4 Template生成代碼:參考此文,可以知道本ORM是如何根據數據庫,生成實體層代碼。有了這個基礎,就可以看懂本文本中所有的T4模板。

DBHelper (支持事務與數據庫變更):參考此文,可以知道本ORM是如何訪問數據庫,如何支持事務,分頁和多種數據庫。

2  實現方法

本文主要關注的藍色ORM部分。

Model:定義了實體的基類。每一張表都會生成對應的實體並繼承此類;

ModelMapping:定義了一張表的結構信息,其中包含了表名、主鍵、字段類型等。每一張表都會生成一個;

ModelMappingReflector: 在程序第一次運行時,反射所有ModelMapping的子類,並將其加入一個字典集合中;

DataAccess<T>: 此類的作用時,根據實體和實體的結構信息(ModelMapping),自動生成SQL來訪問數據庫(Add,Update,Delete);或將數據庫中值加到實體上(GetModel,GetList)。此類幫我們做CRUD的工作,我們不再需要寫每張表基本的增刪改查的工作了,但仍需要寫復雜業務的查詢。每一張表都會生成一個空的dao類並繼承此類。

此ORM的核心類就是DataAccess<T>, 下面我們就拿Add作為示例:

Add 操作代碼

public int Add(T model)
{
    if (model == null)
    {
        throw new ArgumentNullException();
    }

    StringBuilder cmdText = new StringBuilder();
    cmdText.Append("INSERT INTO ").Append(modelMapping.TableName).Append(" (");
    cmdText.Append(string.Join(",", model.ColumnValues.Keys.ToArray()));
    cmdText.Append(") VALUES (@");
    cmdText.Append(string.Join(", @", model.ColumnValues.Keys.ToArray()));
    cmdText.Append(")");

    List<DbParameter> dbParms = new List<DbParameter>();
    foreach (var pair in model.ColumnValues) 
    {
        dbParms.Add(DBHelper.CreateInDbParameter(string.Format("@{0}",pair.Key), modelMapping.ColumnDict[pair.Key].DbDataBype, pair.Value));
    }

    return this.ExecuteNonQuery(CommandType.Text, cmdText.ToString(), dbParms.ToArray());
}

 

當我們寫這樣的代碼時User model=new User(); model.UserName時,實際上會向Model中ColumnValues集合中添加數據。而要生成一個INSERT SQL (INSERT INTO tablename (column1,colum2) VALUES (@column1,@column2)和添加插入參數,我們需要表名,列名,列值和列的類型。在列名和列值就存在於Model中的ColumnValues集合,而列的類型和表名,我們可以在ModelMapping中獲取。

3   示例

static void Main(string[] args) { TestORM(); TestPaging(); Console.ReadLine(); } static void TestORM() { UserDao dao = new UserDao(); try { dao.BeginTransaction(); // add model User mUser1 = new User(); mUser1.ID = "1"; mUser1.UserName = "Mike1"; mUser1.UserPwd = "1234"; mUser1.CreateBy = "System"; mUser1.CreateDate = DateTime.Now; dao.Add(mUser1); Console.WriteLine("Create Model Successfully."); string cmdText = "SELECT * FROM TUser WHERE ID='1' ORDER BY ID;"; List<User> list0 = dao.GetListBySQL(cmdText); foreach (User model in list0) { Console.WriteLine(model.UserName); } Console.WriteLine("Get List Successfully."); //嵌套事務 UserDao dao2 = new UserDao(); try { dao2.BeginTransaction(); //update model User mUser2 = new User(); mUser2.ID = "1"; mUser2.UserName = "Mike.Jiang"; mUser2.UserPwd = null; mUser2.CreateDate = null; dao.Update(mUser2); Console.WriteLine("Update Model Successfully."); User mUser3 = dao.GetModel("1"); if (mUser3 != null) Console.WriteLine(mUser3.UserName); Console.WriteLine("Get Model Successfully."); dao2.CommitTransaction(); } catch { dao2.RollbackTransaction(); } dao.Delete("1"); Console.WriteLine("Delete Model Successfully."); dao.CommitTransaction(); } catch (Exception ex) { Console.WriteLine(ex.Message); dao.RollbackTransaction(); } } static void TestPaging() { UserDao dao = new UserDao(); // add 100 user for (int i = 1; i <= 100; i++) { User mUser1 = new User(); mUser1.ID = i.ToString(); mUser1.UserName = "Mike" + i.ToString(); mUser1.UserPwd = "1234"; mUser1.CreateBy = "System"; mUser1.CreateDate = DateTime.Now; dao.Add(mUser1); } string cmdText = string.Format("SELECT * FROM TUser"); DataTable table = DBHelper.ExecutePagingDataTable(CommandType.Text, cmdText, 1, 10, "ORDER BY ID"); foreach (DataRow row in table.Rows) { Console.WriteLine(row["ID"]); } Console.WriteLine("Get Datatabe paging successfuly."); List<User> list = dao.GetListPaging(cmdText, 2, 10, "ORDER BY ID"); foreach (User m in list) { Console.WriteLine(m.ID); } Console.WriteLine("Get Model list paging successfully."); cmdText = "DELETE FROM TUser"; dao.ExecuteNonQuery(CommandType.Text, cmdText); } View Code

 

 

4  總結

這個版本的ORM示例,示例是沒有認真去寫了,因為不認為會有人用。但是這個ORM的代碼是我認為比較簡單的一個版本,只具有ORM的核心功能,幾個類,只要具有c#基礎的人都能看懂,有興趣的可以看下。後續,自己會加上分頁的Pager相關的內容、數據同步、數據驗證的功能和和根據SQL自動生成實體對象的功能。

所有的源代碼: BaseProject.7z


ORM的代碼生成器大家都用什?

動軟,或者自己寫個小工具
 

一個簡單的個人網頁 附帶源代碼 交作業的 靜態的

For your topic求一個簡單的個人網頁 附帶源代碼 交作業的 靜態的,
聯系我們需要提供你的問題和電子郵件,
如果你有更多的要求也可以告訴我們,
有可能幫你,
請用BaiduHi為我留言,
此回復對於所有需求和和來訪者有效,
ES:\\7A294A3895BAABEE0EDFBD11B27B34C6
 

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