搭建一套自己實用的.net架構(3)【ORM-Dapper+DapperExtensions】


現在成熟的ORM比比皆是,這里只介紹Dapper的使用(最起碼我在使用它,已經運用到項目中,小伙伴們反饋還可以)。

優點:

1、開源、輕量、小巧、上手容易。

2、支持的數據庫還蠻多的, Mysql,SqlLite,Sqlserver,Oracle等一系列的數據庫。

3、Dapper原理通過Emit反射IDataReader的序列隊列來快速的得到和產生對象。性能貌似很牛逼的樣子

缺點:

作為一款ORM太過於輕量級了,根據對象自動生成sql的功能還是空白,需要自己來擴展,

當然這也是優點,  好聲音的導師們經常說某人就是張白紙……  

 

因此針對Dapper已經有很多成熟的擴展項目了,Dapper.Rainbow、Dapper.Contrib,DapperExtensions。

我們這里介紹的是DapperExtensions

 

dapper-dot-net源碼:https://github.com/StackExchange/dapper-dot-net   (更新頻率快,項目包含了各種除了Dapper-Extensions的 擴展項目)

Dapper-Extensions 源碼:https://github.com/tmsmith/Dapper-Extensions 

Dapper-Extensions的優點

1、開源

2、針對Dapper封裝了常用的CRUD方法,有獨立的查詢語法。

3、需要映射的實體類本身0配置,無需加特性什么的。是通過獨立的映射類來處理,可以設置類映射到DB的別名,字段的別名等等。

Dapper-Extensions的缺點:

1、好幾年沒更新了

2、不支持oracle(木有oracle的方言,已經搞定)  

3、不能同時支持多種數據庫(已經搞定)

4、部分代碼有些bug(發現的都搞定了)

 

下面先簡單介紹一下Dapper的基本語法。

Dapper就一個.cs文件,可以放到項目代碼中直接編譯,也可以直接引用DLL文件。

Dapper對DB的操作依賴於Connection,為了支持多庫,咱們用 IDbConnection conn

using (IDbConnection conn = GetConnection())
    {
        const string query = "select * from XO order by id desc";
        return conn.Query<XOEntity>(query,null);
    }

下面是帶參數的語法

int xoID=666; //變量主鍵
using (IDbConnection conn = GetConnection()) { const string query = "select * from XO where Id=@MyID"; return conn.Query<XOEntity>(query, new { MyID = xoID}); }

 

各種方法都重載了事務的操作,一般的數據庫操作都支持。但是每次執行都需要傳遞sql,而且每次都要使用Using,看着不爽啊, 這…… 

好吧下面簡單介紹下使用Dapper-Extensions的基本語法(在Dapper-Extensions  的基礎上用了Repository模式,代碼效果如下)。

            //實體類
            DemoEntity entity = new DemoEntity();

            //根據實體主鍵刪除
            this.Delete<DemoEntity>(entity);

            //根據主鍵ID刪除
            this.Delete<DemoEntity>(1);

            //增加
            this.Insert<DemoEntity>(entity);

            //更新
            bool result = this.Update<DemoEntity>(entity);

            //根據主鍵返回實體
            entity = this.GetById<DemoEntity>(1);

            //返回 行數
            this.Count<DemoEntity>(new { ID = 1 });

            //查詢所有
            IEnumerable<DemoEntity> list = this.GetAll<DemoEntity>();

            IList<ISort> sort = new List<ISort>();
            sort.Add(new Sort { PropertyName = "ID", Ascending = false });


            //條件查詢
            list = this.GetList<DemoEntity>(new { ID = 1, Name = "123" }, sort);

            //orm 拼接條件 查詢
            IList<IPredicate> predList = new List<IPredicate>();
            predList.Add(Predicates.Field<DemoEntity>(p => p.Name, Operator.Like, "不知道%"));
            predList.Add(Predicates.Field<DemoEntity>(p => p.ID, Operator.Eq, 1));
            IPredicateGroup predGroup = Predicates.Group(GroupOperator.And, predList.ToArray());

            

            list = this.GetList<DemoEntity>(predGroup);


            //分頁查詢
            long allRowsCount = 0;
            this.GetPageList<DemoEntity>(1, 10, out allRowsCount, new { ID = 1 }, sort);

 

在說ORM之前,還是要說一下HY.DataAccess這個模塊

 

 

這個模塊是對數據訪問提供的一個Helper的功能,里面包含了 各種DB的SqlHelper,分頁。

DBHelper 都繼承自IDBHelper.cs

using System.Data.Common;
using System.Data;

namespace HY.DataAccess
{
    /// <summary>
    /// 提供對數據庫的基本操作,連接字符串需要在數據庫配置。
    /// </summary>
    public interface IDBHelper
    {

        /// <summary>
        /// 生成分頁SQL語句
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="selectSql"></param>
        /// <param name="sqlCount"></param>
        /// <param name="orderBy"></param>
        /// <returns></returns>
        string GetPagingSql(int pageIndex, int pageSize, string selectSql, string sqlCount, string orderBy);


        /// <summary>
        /// 開始一個事務
        /// </summary>
        /// <returns></returns>
        DbTransaction BeginTractionand();


        /// <summary>
        /// 開始一個事務
        /// </summary>
        /// <param name="connKey">數據庫連接字符key</param>
        DbTransaction BeginTractionand(string connKey);

        /// <summary>
        /// 回滾事務
        /// </summary>
        /// <param name="dbTransaction">要回滾的事務</param>
        void RollbackTractionand(DbTransaction dbTransaction);

        /// <summary>
        /// 結束並確認事務
        /// </summary>
        /// <param name="dbTransaction">要結束的事務</param>
        void CommitTractionand(DbTransaction dbTransaction);




        #region DataSet

        /// <summary>
        /// 執行sql語句,ExecuteDataSet 返回DataSet
        /// </summary>
        /// <param name="commandText">sql語句</param>
        /// <param name="commandType"></param>
        DataSet ExecuteDataSet(string commandText, CommandType commandType);

        /// <summary>
        /// 執行sql語句,ExecuteDataSet 返回DataSet
        /// </summary>
        /// <param name="connKey">數據庫連接字符key</param>
        /// <param name="commandText">sql語句</param>
        /// <param name="commandType"></param>
        DataSet ExecuteDataSet(string connKey, string commandText, CommandType commandType);


        /// <summary>
        /// 執行sql語句,ExecuteDataSet 返回DataSet
        /// </summary>
        /// <param name="commandText">sql語句</param>
        /// <param name="commandType"></param>
        /// <param name="parameterValues">參數</param>
        DataSet ExecuteDataSet(string commandText, CommandType commandType, params DbParameter[] parameterValues);

        /// <summary>
        /// 執行sql語句,ExecuteDataSet 返回DataSet
        /// </summary>
        /// <param name="connKey">數據庫連接字符key</param>
        /// <param name="commandText">sql語句</param>
        /// <param name="commandType"></param>
        /// <param name="parameterValues">參數</param>
        DataSet ExecuteDataSet(string connKey, string commandText, CommandType commandType, params DbParameter[] parameterValues);



        #endregion



        #region ExecuteNonQuery

        /// <summary>
        /// 執行sql語句,返回影響的行數
        /// </summary>
        /// <param name="commandText">sql語句</param>
        /// <param name="commandType"></param>
        int ExecuteNonQuery(string commandText, CommandType commandType);

        /// <summary>
        /// 執行sql語句,返回影響的行數
        /// </summary>
        /// <param name="connKey">數據庫連接字符key</param>
        /// <param name="commandText">sql語句</param>
        /// <param name="commandType"></param>
        int ExecuteNonQuery(string connKey, string commandText, CommandType commandType);

        /// <summary>
        /// 執行sql語句,返回影響的行數
        /// </summary>
        /// <param name="trans">事務對象</param>
        /// <param name="commandText">sql語句</param>
        /// <param name="commandType"></param>
        int ExecuteNonQuery(DbTransaction trans, string commandText, CommandType commandType);

        /// <summary>
        /// 執行sql語句,返回影響的行數
        /// </summary>
        /// <param name="commandText">sql語句</param>
        /// <param name="commandType"></param>
        /// <param name="parameterValues">參數</param>
        int ExecuteNonQuery(string commandText, CommandType commandType, params DbParameter[] parameterValues);

        /// <summary>
        /// 執行sql語句,返回影響的行數
        /// </summary>
        /// <param name="connKey">數據庫連接字符key</param>
        /// <param name="commandText">sql語句</param>
        /// <param name="commandType"></param>
        /// <param name="parameterValues">參數</param>
        int ExecuteNonQuery(string connKey, string commandText, CommandType commandType, params DbParameter[] parameterValues);

        /// <summary>
        /// 執行sql語句,返回影響的行數
        /// </summary>
        /// <param name="trans">事務對象</param>
        /// <param name="commandText">sql語句</param>
        /// <param name="commandType"></param>
        /// <param name="parameterValues">參數</param>
        int ExecuteNonQuery(DbTransaction trans, string commandText, CommandType commandType, params DbParameter[] parameterValues);

        #endregion





        #region IDataReader

        /// <summary>
        /// 執行sql語句,ExecuteReader 返回IDataReader
        /// </summary>   
        /// <param name="commandText">sql語句</param>
        /// <param name="commandType"></param>
        IDataReader ExecuteReader(string commandText, CommandType commandType);

        /// <summary>
        /// 執行sql語句,ExecuteReader 返回IDataReader
        /// </summary> 
        /// <param name="commandText">sql語句</param>
        /// <param name="commandType"></param>
        /// <param name="parameterValues">參數</param>
        IDataReader ExecuteReader(string commandText, CommandType commandType, params DbParameter[] parameterValues);

        /// <summary>
        /// 執行sql語句,ExecuteReader 返回IDataReader
        /// </summary>
        /// <param name="connKey">數據庫連接字符key</param>        
        /// <param name="commandText">sql語句</param>
        /// <param name="commandType"></param>
        IDataReader ExecuteReader(string connKey, string commandText, CommandType commandType);

        /// <summary>
        /// 執行sql語句,ExecuteReader 返回IDataReader
        /// </summary>
        /// <param name="connKey">數據庫連接字符key</param>        
        /// <param name="commandText">sql語句</param>
        /// <param name="commandType"></param>
        /// <param name="parameterValues">參數</param>
        IDataReader ExecuteReader(string connKey, string commandText, CommandType commandType, params DbParameter[] parameterValues);

        #endregion


        #region ExecuteScalar

        /// <summary>
        /// 執行sql語句,ExecuteScalar 返回第一行第一列的值
        /// </summary>
        /// <param name="commandText">sql語句</param>
        /// <param name="commandType"></param>
        object ExecuteScalar(string commandText, CommandType commandType);


        /// <summary>
        /// 執行sql語句,ExecuteScalar 返回第一行第一列的值
        /// </summary>
        /// <param name="commandText">sql語句</param>
        /// <param name="commandType"></param>
        /// <param name="parameterValues">參數</param>
        object ExecuteScalar(string commandText, CommandType commandType, params DbParameter[] parameterValues);

        /// <summary>
        /// 執行sql語句,ExecuteScalar 返回第一行第一列的值
        /// </summary>
        /// <param name="trans">事務</param>
        /// <param name="commandText">sql語句</param>
        /// <param name="commandType"></param>
        object ExecuteScalar(DbTransaction trans, string commandText, CommandType commandType);

        /// <summary>
        /// 執行sql語句,ExecuteScalar 返回第一行第一列的值
        /// </summary>
        /// <param name="connKey">數據庫連接字符key</param>
        /// <param name="commandText">sql語句</param>
        /// <param name="commandType"></param>
        object ExecuteScalar(string connKey, string commandText, CommandType commandType);


        /// <summary>
        /// 執行sql語句,ExecuteScalar 返回第一行第一列的值
        /// </summary>
        /// <param name="connKey">數據庫連接字符key</param>
        /// <param name="commandText">sql語句</param>
        /// <param name="commandType"></param>
        /// <param name="parameterValues">參數</param>
        object ExecuteScalar(string connKey, string commandText, CommandType commandType, params DbParameter[] parameterValues);

        /// <summary>
        /// 執行sql語句,ExecuteScalar 返回第一行第一列的值
        /// </summary>
        /// <param name="trans">事務</param>
        /// <param name="commandText">sql語句</param>
        /// <param name="commandType"></param>
        /// <param name="parameterValues">參數</param>
        /// <returns></returns>
        object ExecuteScalar(DbTransaction trans, string commandText, CommandType commandType, params DbParameter[] parameterValues);
        #endregion



    }
}
View Code

 

IDBSession.cs 對數據訪問對象的定義

using System;
using System.Data;

namespace HY.DataAccess
{

    /// <summary>
    /// 數據庫接口
    /// </summary>
    public interface IDatabase
    {
        IDbConnection Connection { get; }

        DatabaseType DatabaseType { get; }

        string ConnKey { get; }
    }

    /// <summary>
    /// 數據庫類對象
    /// </summary>
    public class Database : IDatabase
    {
        public IDbConnection Connection { get; private set; }

        public DatabaseType DatabaseType { get; private set; }

        public string ConnKey { get; set; }

        public Database(IDbConnection connection)
        {
            Connection = connection;
        }


        public Database(DatabaseType dbType, string connKey)
        {
            DatabaseType = dbType;
            ConnKey = connKey;
            Connection = SqlConnectionFactory.CreateSqlConnection(dbType, connKey);
        }

    }


    /// <summary>
    /// 數據連接事務的Session接口
    /// </summary>
    public interface IDBSession : IDisposable
    {
        string ConnKey { get; }
        DatabaseType DatabaseType { get; }
        IDbConnection Connection { get; }
        IDbTransaction Transaction { get; }
        IDbTransaction Begin(IsolationLevel isolation = IsolationLevel.ReadCommitted);
        void Commit();
        void Rollback();
    }
}
View Code

 

SqlConnectionFactory.cs 這個類是采用工廠模式創建DB連接的封裝,代碼如下:

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;

namespace HY.DataAccess
{

    public enum DatabaseType
    {    
        SqlServer,
        MySql,
        Oracle,
        DB2
    }

    public class SqlConnectionFactory
    {
        public static IDbConnection CreateSqlConnection(DatabaseType dbType, string strKey)
        {
            IDbConnection connection = null;
            string strConn = ConfigurationManager.ConnectionStrings[strKey].ConnectionString;

            switch (dbType)
            {
                case DatabaseType.SqlServer:
                    connection = new System.Data.SqlClient.SqlConnection(strConn);
                    break;
                case DatabaseType.MySql:
                    //connection = new MySql.Data.MySqlClient.MySqlConnection(strConn);
                    //break;
                case DatabaseType.Oracle:
                    //connection = new Oracle.DataAccess.Client.OracleConnection(strConn);
                    connection = new System.Data.OracleClient.OracleConnection(strConn);
                    break;
                case DatabaseType.DB2:
                    connection = new System.Data.OleDb.OleDbConnection(strConn);
                    break;
            }
            return connection;
        }
    }
}
View Code

 ORM也不是萬能的,比如做大數據的批量插入什么的,還是需要SqlHelper,加上有的人就喜歡DataTable或者DataSet。

所以SqlHelper作為根基,ORM作為輔助,萬無一失啊。

 

下面說說ORM這塊的實現方式。見下截圖

 

IDataServiceRepository.cs(提供業務層使用,里面的方法不支持傳遞sql,包含sql的語句最好還是放在數據層操作的好)

using System.Collections.Generic;
using System.Data;
using DapperExtensions;
using HY.DataAccess;

namespace HY.ORM
{
    public interface IDataServiceRepository
    {
        IDBSession DBSession { get; }

        T GetById<T>(dynamic primaryId) where T : class;
        IEnumerable<T> GetByIds<T>(IList<dynamic> ids) where T : class;
        IEnumerable<T> GetAll<T>() where T : class;


        int Count<T>(object predicate, bool buffered = false) where T : class;

        //lsit
        IEnumerable<T> GetList<T>(object predicate = null, IList<ISort> sort = null, bool buffered = false) where T : class;

        IEnumerable<T> GetPageList<T>(int pageIndex, int pageSize, out long allRowsCount, object predicate = null, IList<ISort> sort = null, bool buffered = true) where T : class;


        dynamic Insert<T>(T entity, IDbTransaction transaction = null) where T : class;
        bool InsertBatch<T>(IEnumerable<T> entityList, IDbTransaction transaction = null) where T : class;
        bool Update<T>(T entity, IDbTransaction transaction = null) where T : class;
        bool UpdateBatch<T>(IEnumerable<T> entityList, IDbTransaction transaction = null) where T : class;
        int Delete<T>(dynamic primaryId, IDbTransaction transaction = null) where T : class;
        int DeleteList<T>(object predicate, IDbTransaction transaction = null) where T : class;
        bool DeleteBatch<T>(IEnumerable<dynamic> ids, IDbTransaction transaction = null) where T : class;
    }
}
View Code

  IDataRepository.cs(提供數據層使用,繼承了上面的IDataServiceRepository,支持傳入sql)

using System;
using System.Collections.Generic;
using System.Data;
using Dapper;
using HY.DataAccess;

namespace HY.ORM
{
    public interface IDataRepository : IDataServiceRepository
    {
        IDBSession DBSession { get; }
            
        IEnumerable<T> Get<T>(string sql, dynamic param = null, bool buffered = true) where T : class;
        IEnumerable<dynamic> Get(string sql, dynamic param = null, bool buffered = true);
        IEnumerable<TReturn> Get<TFirst, TSecond, TReturn>(string sql, Func<TFirst, TSecond, TReturn> map,
            dynamic param = null, IDbTransaction transaction = null, bool buffered = true,
            string splitOn = "Id", int? commandTimeout = null);

         IEnumerable<TReturn> Get<TFirst, TSecond,TThird, TReturn>(string sql, Func<TFirst, TSecond,TThird, TReturn> map,
            dynamic param = null, IDbTransaction transaction = null, bool buffered = true,
            string splitOn = "Id", int? commandTimeout = null);

        SqlMapper.GridReader GetMultiple(string sql, dynamic param = null, IDbTransaction transaction = null,
            int? commandTimeout = null, CommandType? commandType = null);

 
        IEnumerable<T> GetPage<T>(int pageIndex, int pageSize, out long allRowsCount, string sql, dynamic param = null, string allRowsCountSql=null,  dynamic allRowsCountParam = null, bool buffered = true) where T : class;
      
        Int32 Execute(string sql, dynamic param = null, IDbTransaction transaction = null);


    }
}
View Code

  RepositoryServiceBase.cs(IDataServiceRepository的實現類)

using System.Collections.Generic;
using System.Data;
using System.Linq;
using Dapper;
using DapperExtensions;
using HY.DataAccess;

namespace HY.ORM
{
    public class RepositoryServiceBase : IDataServiceRepository
    {
        public RepositoryServiceBase()
        {
        }
        public RepositoryServiceBase(IDBSession dbSession)
        {
            DBSession = dbSession;
        }


        public IDBSession DBSession { get; private set; }

        public void SetDBSession(IDBSession dbSession)
        {
            DBSession = dbSession;
        }


        /// <summary>
        /// 根據Id獲取實體
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="primaryId"></param>
        /// <returns></returns>
        public T GetById<T>(dynamic primaryId) where T : class
        {
            return DBSession.Connection.Get<T>(primaryId as object, databaseType: DBSession.DatabaseType);
        }

        /// <summary>
        /// 根據多個Id獲取多個實體
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="ids"></param>
        /// <returns></returns>
        public IEnumerable<T> GetByIds<T>(IList<dynamic> ids) where T : class
        {
            var tblName = string.Format("dbo.{0}", typeof(T).Name);
            var idsin = string.Join(",", ids.ToArray<dynamic>());
            var sql = "SELECT * FROM @table WHERE Id in (@ids)";
            IEnumerable<T> dataList = DBSession.Connection.Query<T>(sql, new { table = tblName, ids = idsin });
            return dataList;
        }

        /// <summary>
        /// 獲取全部數據集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public IEnumerable<T> GetAll<T>() where T : class
        {
            return DBSession.Connection.GetList<T>(databaseType: DBSession.DatabaseType);
        }


        /// <summary>
        /// 統計記錄總數
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="predicate"></param>
        /// <param name="buffered"></param>
        /// <returns></returns>
        public int Count<T>(object predicate, bool buffered = false) where T : class
        {
            return DBSession.Connection.Count<T>(predicate, databaseType: DBSession.DatabaseType);
        }

        /// <summary>
        /// 查詢列表數據
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="predicate"></param>
        /// <param name="sort"></param>
        /// <param name="buffered"></param>
        /// <returns></returns>
        public IEnumerable<T> GetList<T>(object predicate = null, IList<ISort> sort = null,
            bool buffered = false) where T : class
        {
            return DBSession.Connection.GetList<T>(predicate, sort, null, null, buffered, databaseType: DBSession.DatabaseType);
        }


        /// <summary>
        /// 分頁
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="allRowsCount"></param>
        /// <param name="predicate"></param>
        /// <param name="sort"></param>
        /// <param name="buffered"></param>
        /// <returns></returns>
        public IEnumerable<T> GetPageList<T>(int pageIndex, int pageSize, out long allRowsCount,
            object predicate = null, IList<ISort> sort = null, bool buffered = true) where T : class
        {
            if (sort == null)
            {
                sort = new List<ISort>();
            }
            IEnumerable<T> entityList = DBSession.Connection.GetPage<T>(predicate, sort, pageIndex, pageSize, null, null, buffered, databaseType: DBSession.DatabaseType);
            allRowsCount = DBSession.Connection.Count<T>(predicate, databaseType: DBSession.DatabaseType);
            return entityList;
        }




        /// <summary>
        /// 插入單條記錄
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <param name="transaction"></param>
        /// <returns></returns>
        public dynamic Insert<T>(T entity, IDbTransaction transaction = null) where T : class
        {
            dynamic result = DBSession.Connection.Insert<T>(entity, transaction, databaseType: DBSession.DatabaseType);
            return result;
        }

        /// <summary>
        /// 更新單條記錄
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <param name="transaction"></param>
        /// <returns></returns>
        public bool Update<T>(T entity, IDbTransaction transaction = null) where T : class
        {
            bool isOk = DBSession.Connection.Update<T>(entity, transaction, databaseType: DBSession.DatabaseType);
            return isOk;
        }

        /// <summary>
        /// 刪除單條記錄
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="primaryId"></param>
        /// <param name="transaction"></param>
        /// <returns></returns>
        public int Delete<T>(dynamic primaryId, IDbTransaction transaction = null) where T : class
        {
            var entity = GetById<T>(primaryId);
            var obj = entity as T;
            int isOk = DBSession.Connection.Delete<T>(obj, databaseType: DBSession.DatabaseType);
            return isOk;
        }

        /// <summary>
        /// 刪除單條記錄
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="predicate"></param>
        /// <param name="transaction"></param>
        /// <returns></returns> 
        public int DeleteList<T>(object predicate = null, IDbTransaction transaction = null) where T : class
        {
            return DBSession.Connection.Delete<T>(predicate, transaction, databaseType: DBSession.DatabaseType);
        }

        /// <summary>
        /// 批量插入功能
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entityList"></param>
        /// <param name="transaction"></param>
        public bool InsertBatch<T>(IEnumerable<T> entityList, IDbTransaction transaction = null) where T : class
        {
            bool isOk = false;
            foreach (var item in entityList)
            {
                Insert<T>(item, transaction);
            }
            isOk = true;
            return isOk;
        }

        /// <summary>
        /// 批量更新()
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entityList"></param>
        /// <param name="transaction"></param>
        /// <returns></returns>
        public bool UpdateBatch<T>(IEnumerable<T> entityList, IDbTransaction transaction = null) where T : class
        {
            bool isOk = false;
            foreach (var item in entityList)
            {
                Update<T>(item, transaction);
            }
            isOk = true;
            return isOk;
        }

        /// <summary>
        /// 批量刪除
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="ids"></param>
        /// <param name="transaction"></param>
        /// <returns></returns>
        public bool DeleteBatch<T>(IEnumerable<dynamic> ids, IDbTransaction transaction = null) where T : class
        {
            bool isOk = false;
            foreach (var id in ids)
            {
                Delete<T>(id, transaction);
            }
            isOk = true;
            return isOk;
        }

    }
}
View Code

 RepositoryBase.cs(IDataRepository的實現類)

using System;
using System.Collections.Generic;
using System.Data;
using Dapper;
using DapperExtensions;
using HY.DataAccess;

namespace HY.ORM
{
    /// <summary>
    /// Repository基類
    /// </summary>
    public class RepositoryBase : RepositoryServiceBase, IDataRepository
    {


        public RepositoryBase()
        {
        }

        public new void SetDBSession(IDBSession dbSession)
        {
            base.SetDBSession(dbSession);
        }


        public RepositoryBase(IDBSession dbSession)
            : base(dbSession)
        {
        }



        /// <summary>
        /// 根據條件篩選出數據集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <param name="param"></param>
        /// <param name="buffered"></param>
        /// <returns></returns>
        public IEnumerable<T> Get<T>(string sql, dynamic param = null, bool buffered = true) where T : class
        {

            return DBSession.Connection.Query<T>(sql, param as object, DBSession.Transaction, buffered);
        }

        /// <summary>
        /// 根據條件篩選數據集合
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="param"></param>
        /// <param name="buffered"></param>
        /// <returns></returns>
        public IEnumerable<dynamic> Get(string sql, dynamic param = null, bool buffered = true)
        {
            return DBSession.Connection.Query(sql, param as object, DBSession.Transaction, buffered);
        }

        /// <summary>
        /// 分頁查詢
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="allRowsCount"></param>
        /// <param name="sql"></param>
        /// <param name="param"></param>
        /// <param name="allRowsCountSql"></param>
        /// <param name="allRowsCountParam"></param>
        /// <param name="buffered"></param>
        /// <returns></returns>
        public IEnumerable<T> GetPage<T>(int pageIndex, int pageSize, out long allRowsCount, string sql, dynamic param = null, string allRowsCountSql = null, dynamic allRowsCountParam = null, bool buffered = true) where T : class
        {
            IEnumerable<T> entityList = DBSession.Connection.GetPage<T>(pageIndex, pageSize, out allRowsCount, sql, param as object, allRowsCountSql, null, null, buffered, databaseType: DBSession.DatabaseType);
            return entityList;
        }

        /// <summary>
        /// 根據表達式篩選
        /// </summary>
        /// <typeparam name="TFirst"></typeparam>
        /// <typeparam name="TSecond"></typeparam>
        /// <typeparam name="TReturn"></typeparam>
        /// <param name="sql"></param>
        /// <param name="map"></param>
        /// <param name="param"></param>
        /// <param name="transaction"></param>
        /// <param name="buffered"></param>
        /// <param name="splitOn"></param>
        /// <param name="commandTimeout"></param>
        /// <returns></returns>
        public IEnumerable<TReturn> Get<TFirst, TSecond, TReturn>(string sql, Func<TFirst, TSecond, TReturn> map,
            dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id",
            int? commandTimeout = null)
        {
            return DBSession.Connection.Query(sql, map, param as object, transaction, buffered, splitOn);
        }

        /// <summary>
        /// 根據表達式篩選
        /// </summary>
        /// <typeparam name="TFirst"></typeparam>
        /// <typeparam name="TSecond"></typeparam>
        /// <typeparam name="TReturn"></typeparam>
        /// <param name="sql"></param>
        /// <param name="map"></param>
        /// <param name="param"></param>
        /// <param name="transaction"></param>
        /// <param name="buffered"></param>
        /// <param name="splitOn"></param>
        /// <param name="commandTimeout"></param>
        /// <returns></returns>
        public IEnumerable<TReturn> Get<TFirst, TSecond, TThird, TReturn>(string sql, Func<TFirst, TSecond, TThird, TReturn> map,
            dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id",
            int? commandTimeout = null)
        {
            return DBSession.Connection.Query(sql, map, param as object, transaction, buffered, splitOn);
        }



        /// <summary>
        /// 獲取多實體集合
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="param"></param>
        /// <param name="transaction"></param>
        /// <param name="commandTimeout"></param>
        /// <param name="commandType"></param>
        /// <returns></returns>
        public SqlMapper.GridReader GetMultiple(string sql, dynamic param = null, IDbTransaction transaction = null,
            int? commandTimeout = null, CommandType? commandType = null)
        {
            return DBSession.Connection.QueryMultiple(sql, param as object, transaction, commandTimeout, commandType);
        }

        /// <summary>
        /// 執行sql操作
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        public int Execute(string sql, dynamic param = null, IDbTransaction transaction = null)
        {
            return DBSession.Connection.Execute(sql, param as object, transaction);
        }


    }
}
View Code

 

 說起DapperExtensions修改的小地方還蠻多的,下圖是一個代碼比較的截圖。所以一會把代碼打包貼上來吧(見文章結尾)。

 

 上述代碼就可以編譯成 HY.ORM.DLL文件了。

 

下面就可以在 自己業務層繼承HY.ORM中的RepositoryServiceBase類   ,數據層繼承HY.ORM中的 RepositoryBase類。

通過各自的構造函數或者, SetDBSession(Helper.CreateDBSession());  進行數據連接初始化。

 

 

接下來配置實體類和DB的映射:

    public class DemoEntity
    {        
        public int ID { get; set; }

        public string Name { get; set; }
    }

    [Serializable]
    public class DomoEntityORMMapper : ClassMapper<DemoEntity>
    {
        public DomoEntityORMMapper()
        {
            base.Table("Demo");
            //Map(f => f.UserID).Ignore();//設置忽略
            //Map(f => f.Name).Key(KeyType.Identity);//設置主鍵  (如果主鍵名稱不包含字母“ID”,請設置)           
            AutoMap();
        }
    }

 

這樣就可以在類中  實現   this.Get<DemoEntity>("select * from  Demo where ID=@ID", new { ID = 1 });   這樣的語法了。

 

 

具體的使用方發

      下圖是我要介紹實現的項目截圖:

其實也是三層,只是名字不一樣而已。  

HY.Web( UI層,MVC)

HY.Web.Iservice( 服務接口層)

HY.Web.Service(服務層,HY.Web.Iservice的實現類,    你也可以理解為業務邏輯層BLL)

HY.Web.DAO(數據訪問層,   你也可以理解為DAL)

HY.Web.Entity(實體層,  目前只定義了數據實體, 如果你的系統需要給app提供數據, 那么傳輸的數據要精簡,就需要單獨定義DTO了。   )

 

就那用戶表來做個實例吧,表結構如下:(下圖是用代碼生成器截圖效果,可以直接修改數據庫的描述信息,開發利器。需要的朋友點這里【CodeBuilder-RazorEngine】

 

 

HY.Web.Entity

在HY.Web.Entity的項目中新建Sys_UsersEntity.cs  定義實體類

View Code

 

HY.Web.DAO 

定義基類 BaseRepository.cs (可以設置默認的DBsession,方便擴展其它東東)

View Code

 

定義數據訪問層 Sys_UsersRepository.cs (代碼里可以封裝任何需要寫sql 的代碼)

View Code

 

HY.Web.IService

定義接口 ISys_UsersService.cs ,提供給UI訪問。

View Code

 

HY.Web.Service

定義BaseService.cs,(可以設置默認的DBsession,方便擴展其它東東)

View Code

 

定義Sys_UsersService.cs, 去實現ISys_UsersService。

View Code

 

HY.Web

1、定義相關的Controller

2、ISys_UsersService iSys_UsersService = new Sys_UsersService();  (這塊其實可以使用 IoC, 相關內容且聽后續分解)

3、調用接口

View Code

 

 

 

下載:

HY.DataAccess

修改后的DapperExtensions:Dapperextensions.RAR 

 

 

ps:已經更新版本了,  加入了對lambda的擴展,點擊這里進入

 

 

相關文章:

搭建一套自己實用的.net架構(1)【概述】

搭建一套自己實用的.net架構(2)【日志模塊-log4net】

搭建一套自己實用的.net架構(3)【ORM-Dapper+DapperExtensions】

 搭建一套自己實用的.net架構(3)續 【ORM Dapper+DapperExtensions+Lambda】

 搭建一套自己實用的.net架構(4)【CodeBuilder-RazorEngine】

 

原文鏈接:http://www.cnblogs.com/hy59005271/p/4759623.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM