国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

一個(gè)ORM的實(shí)現(xiàn)(附源代碼)

2019-11-17 03:00:12
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

一個(gè)ORM的實(shí)現(xiàn)(附源代碼)

2014-07-30 23:31 by Mike.Jiang, ... 閱讀, ... 評(píng)論, 收藏, 編輯

1  前言

經(jīng)過(guò)一段時(shí)間的編寫(xiě),終于有出來(lái)一個(gè)穩(wěn)定的版本,期間考慮了多種解決方案也偷偷學(xué)了下園子里面大神們的作品。

已經(jīng)有很多的ORM框架,為什么要自己實(shí)現(xiàn)一個(gè)?我的原因是在遇到特殊需求時(shí),可以在ORM中加入特定的代碼。如 :根據(jù)數(shù)據(jù)庫(kù)的字段長(zhǎng)度和可空性做基本的數(shù)據(jù)驗(yàn)證,在ORM中解決數(shù)據(jù)修改時(shí)的同步問(wèn)題…

本文主要關(guān)注的是如何實(shí)現(xiàn)ORM方面,其它的大家可以參考以下兩篇文章:

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

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

2  實(shí)現(xiàn)方法

本文主要關(guān)注的藍(lán)色ORM部分。

Model:定義了實(shí)體的基類(lèi)。每一張表都會(huì)生成對(duì)應(yīng)的實(shí)體并繼承此類(lèi);

ModelMapping:定義了一張表的結(jié)構(gòu)信息,其中包含了表名、主鍵、字段類(lèi)型等。每一張表都會(huì)生成一個(gè);

ModelMappingReflector: 在程序第一次運(yùn)行時(shí),反射所有ModelMapping的子類(lèi),并將其加入一個(gè)字典集合中;

Dataaccess<T>: 此類(lèi)的作用時(shí),根據(jù)實(shí)體和實(shí)體的結(jié)構(gòu)信息(ModelMapping),自動(dòng)生成SQL來(lái)訪問(wèn)數(shù)據(jù)庫(kù)(Add,Update,Delete);或?qū)?shù)據(jù)庫(kù)中值加到實(shí)體上(GetModel,GetList)。此類(lèi)幫我們做CRUD的工作,我們不再需要寫(xiě)每張表基本的增刪改查的工作了,但仍需要寫(xiě)復(fù)雜業(yè)務(wù)的查詢(xún)。每一張表都會(huì)生成一個(gè)空的dao類(lèi)并繼承此類(lèi)。

此ORM的核心類(lèi)就是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());}

當(dāng)我們寫(xiě)這樣的代碼時(shí)User model=new User(); model.UserName時(shí),實(shí)際上會(huì)向Model中ColumnValues集合中添加數(shù)據(jù)。而要生成一個(gè)INSERT SQL (INSERT INTO tablename (column1,colum2) VALUES (@column1,@column2)和添加插入?yún)?shù),我們需要表名,列名,列值和列的類(lèi)型。在列名和列值就存在于Model中的ColumnValues集合,而列的類(lèi)型和表名,我們可以在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.");        //嵌套事務(wù)        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  總結(jié)

這個(gè)版本的ORM示例,示例是沒(méi)有認(rèn)真去寫(xiě)了,因?yàn)椴徽J(rèn)為會(huì)有人用。但是這個(gè)ORM的代碼是我認(rèn)為比較簡(jiǎn)單的一個(gè)版本,只具有ORM的核心功能,幾個(gè)類(lèi),只要具有c#基礎(chǔ)的人都能看懂,有興趣的可以看下。后續(xù),自己會(huì)加上分頁(yè)的Pager相關(guān)的內(nèi)容、數(shù)據(jù)同步、數(shù)據(jù)驗(yàn)證的功能和和根據(jù)SQL自動(dòng)生成實(shí)體對(duì)象的功能。

所有的源代碼: BasePRoject.7z


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 周至县| 广东省| 黄骅市| 吉林市| 安丘市| 陕西省| 兰溪市| 巴塘县| 安平县| 资溪县| 锡林浩特市| 邵阳市| 嘉义市| 土默特右旗| 会昌县| 太仓市| 公主岭市| 江源县| 麻栗坡县| 高密市| 晴隆县| 库伦旗| 郸城县| 自治县| 新巴尔虎左旗| 新绛县| 抚宁县| 特克斯县| 桐城市| 尤溪县| 安乡县| 泰顺县| 潞西市| 芜湖市| 开远市| 大安市| 澳门| 左权县| 安阳市| 三亚市| 亳州市|