ORM-Dapper + DapperExtensions



Orm Dapper Dapperextensions



http://www.cnblogs.com/hy59005271/p/4759623.html

今では成熟したORMがたくさんあります。ここでは、Dapperの使用法のみを紹介します(少なくとも私はそれを使用し、プロジェクトに適用されており、友人からのフィードバックは問題ありません)。



利点:

1、オープンソース、軽量、コンパクト、簡単に始められます。



2、サポートされているデータベースはかなりたくさんあります、 Mysql、SqlLite、Sqlserver、Oracle 一連のデータベースを待ちます。

3. Dapperの原則は、IDataReaderのシーケンスキューを反映して、Emitによってオブジェクトをすばやく取得および生成します。パフォーマンスは素晴らしいようです

短所:



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、オラクルをサポートしていません(木材にはオラクル方言があり、修正されています)

3、同時に複数のデータベースをサポートすることはできません(すでに修正済み)

4、いくつかのコードいくつかのバグ(すべて発見された)

未満 シンプル Dapperの基本的な構文を紹介します。

Dapperは、プロジェクトコードに直接コンパイルできる、またはDLLファイルを直接参照できる.csファイルです。

Dapperは、DB操作をConnectionに依存しています。複数のライブラリをサポートするために、IDbConnectionconnを使用します。

using System.Data.Common using System.Data namespace HY.DataAccess { /// /// Provides basic operations on the database. The connection string needs to be configured in the database. /// public interface IDBHelper { /// /// Generate a paging SQL statement /// /// /// /// /// /// /// string GetPagingSql(int pageIndex, int pageSize, string selectSql, string sqlCount, string orderBy) /// /// Start a transaction /// /// DbTransaction BeginTractionand() /// /// Start a transaction /// /// Database connection character key DbTransaction BeginTractionand(string connKey) /// /// Rollback transaction /// /// The transaction to be rolled back void RollbackTractionand(DbTransaction dbTransaction) /// /// End and confirm the transaction /// /// The transaction to end void CommitTractionand(DbTransaction dbTransaction) #region DataSet /// /// Execute the sql statement, ExecuteDataSet returns the DataSet /// /// sql statement /// DataSet ExecuteDataSet(string commandText, CommandType commandType) /// /// Execute the sql statement, ExecuteDataSet returns the DataSet /// /// Database connection character key /// sql statement /// DataSet ExecuteDataSet(string connKey, string commandText, CommandType commandType) /// /// Execute the sql statement, ExecuteDataSet returns the DataSet /// /// sql statement /// /// parameters DataSet ExecuteDataSet(string commandText, CommandType commandType, params DbParameter[] parameterValues) /// /// Execute the sql statement, ExecuteDataSet returns the DataSet /// /// Database connection character key /// sql statement /// /// parameters DataSet ExecuteDataSet(string connKey, string commandText, CommandType commandType, params DbParameter[] parameterValues) #endregion #region ExecuteNonQuery /// /// Execute sql statement, return the number of rows affected /// /// sql statement /// int ExecuteNonQuery(string commandText, CommandType commandType) /// /// Execute sql statement, return the number of rows affected /// /// Database connection character key /// sql statement /// int ExecuteNonQuery(string connKey, string commandText, CommandType commandType) /// /// Execute sql statement, return the number of rows affected /// /// transaction object /// sql statement /// int ExecuteNonQuery(DbTransaction trans, string commandText, CommandType commandType) /// /// Execute sql statement, return the number of rows affected /// /// sql statement /// /// parameters int ExecuteNonQuery(string commandText, CommandType commandType, params DbParameter[] parameterValues) /// /// Execute sql statement, return the number of rows affected /// /// Database connection character key /// sql statement /// /// parameters int ExecuteNonQuery(string connKey, string commandText, CommandType commandType, params DbParameter[] parameterValues) /// /// Execute sql statement, return the number of rows affected /// /// transaction object /// sql statement /// /// parameters int ExecuteNonQuery(DbTransaction trans, string commandText, CommandType commandType, params DbParameter[] parameterValues) #endregion #region IDataReader /// /// Execute the sql statement, ExecuteReader returns IDataReader /// /// sql statement /// IDataReader ExecuteReader(string commandText, CommandType commandType) /// /// Execute the sql statement, ExecuteReader returns IDataReader /// /// sql statement /// /// parameters IDataReader ExecuteReader(string commandText, CommandType commandType, params DbParameter[] parameterValues) /// /// Execute the sql statement, ExecuteReader returns IDataReader /// /// Database connection character key /// sql statement /// IDataReader ExecuteReader(string connKey, string commandText, CommandType commandType) /// /// Execute the sql statement, ExecuteReader returns IDataReader /// /// Database connection character key /// sql statement /// /// parameters IDataReader ExecuteReader(string connKey, string commandText, CommandType commandType, params DbParameter[] parameterValues) #endregion #region ExecuteScalar /// /// Execute the sql statement, ExecuteScalar returns the value of the first column of the first row /// /// sql statement /// object ExecuteScalar(string commandText, CommandType commandType) /// /// Execute the sql statement, ExecuteScalar returns the value of the first column of the first row /// /// sql statement /// /// parameters object ExecuteScalar(string commandText, CommandType commandType, params DbParameter[] parameterValues) /// /// Execute the sql statement, ExecuteScalar returns the value of the first column of the first row /// /// transaction /// sql statement /// object ExecuteScalar(DbTransaction trans, string commandText, CommandType commandType) /// /// Execute the sql statement, ExecuteScalar returns the value of the first column of the first row /// /// Database connection character key /// sql statement /// object ExecuteScalar(string connKey, string commandText, CommandType commandType) /// /// Execute the sql statement, ExecuteScalar returns the value of the first column of the first row /// /// Database connection character key /// sql statement /// /// parameters object ExecuteScalar(string connKey, string commandText, CommandType commandType, params DbParameter[] parameterValues) /// /// Execute the sql statement, ExecuteScalar returns the value of the first column of the first row /// /// transaction /// sql statement /// /// parameters /// object ExecuteScalar(DbTransaction trans, string commandText, CommandType commandType, params DbParameter[] parameterValues) #endregion } }

以下は、パラメーターを使用した構文です。

画像

using System using System.Data namespace HY.DataAccess { /// /// Database interface /// public interface IDatabase { IDbConnection Connection { get } DatabaseType DatabaseType { get } string ConnKey { get } } /// /// Database class object /// 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) } } /// /// Session interface for data connection transactions /// 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() } }

画像

さまざまなメソッドがトランザクションの操作を過負荷にします。これは、一般的なデータベース操作でサポートされています。しかし、SQLを渡す必要があるたびに、また、Usingを使用するたびに、見栄えが悪くなります...

わかりました、以下 シンプル Dapper-Extensionsを使用する基本的な構文を紹介します(リポジトリモードはDapper-Extensionsに基づいて使用され、コード効果は次のとおりです)。

画像

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 } } }

画像

ORMについて話す前に、モジュールHY.DataAccessについて話す必要があります。

このモジュールは、データアクセス用のヘルパー関数であり、さまざまなDBSqlHelperページングが含まれています。

DBHelperはIDBHelper.csから継承します

using System.Collections.Generic using System.Data using DapperExtensions using HY.DataAccess namespace HY.ORM { public interface IDataServiceRepository { IDBSession DBSession { get } T GetById(dynamic primaryId) where T : class IEnumerable GetByIds(IList ids) where T : class IEnumerable GetAll() where T : class int Count(object predicate, bool buffered = false) where T : class //lsit IEnumerable GetList(object predicate = null, IList sort = null, bool buffered = false) where T : class IEnumerable GetPageList(int pageIndex, int pageSize, out long allRowsCount, object predicate = null, IList sort = null, bool buffered = true) where T : class dynamic Insert(T entity, IDbTransaction transaction = null) where T : class bool InsertBatch(IEnumerable entityList, IDbTransaction transaction = null) where T : class bool Update(T entity, IDbTransaction transaction = null) where T : class bool UpdateBatch(IEnumerable entityList, IDbTransaction transaction = null) where T : class int Delete(dynamic primaryId, IDbTransaction transaction = null) where T : class int DeleteList(object predicate, IDbTransaction transaction = null) where T : class bool DeleteBatch(IEnumerable ids, IDbTransaction transaction = null) where T : class } }

データアクセスオブジェクトのIDBSession.cs定義

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 Get(string sql, dynamic param = null, bool buffered = true) where T : class IEnumerable Get(string sql, dynamic param = null, bool buffered = true) IEnumerable Get(string sql, Func map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = 'Id', int? commandTimeout = null) IEnumerable Get(string sql, Func 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 GetPage(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) } }

SqlConnectionFactory.csこのクラスは、ファクトリモードでDB接続を作成するパッケージです。コードは次のとおりです。

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 } /// /// Get entity based on Id /// /// /// /// public T GetById(dynamic primaryId) where T : class { return DBSession.Connection.Get(primaryId as object, databaseType: DBSession.DatabaseType) } /// /// Get multiple entities based on multiple Ids /// /// /// /// public IEnumerable GetByIds(IList ids) where T : class { var tblName = string.Format('dbo.{0}', typeof(T).Name) var idsin = string.Join(',', ids.ToArray()) var sql = 'SELECT * FROM @table WHERE Id in (@ids)' IEnumerable dataList = DBSession.Connection.Query(sql, new { table = tblName, ids = idsin }) return dataList } /// /// Get all data collections /// /// /// public IEnumerable GetAll() where T : class { return DBSession.Connection.GetList(databaseType: DBSession.DatabaseType) } /// /// Total number of statistics /// /// /// /// /// public int Count(object predicate, bool buffered = false) where T : class { return DBSession.Connection.Count(predicate, databaseType: DBSession.DatabaseType) } /// /// Query list data /// /// /// /// /// /// public IEnumerable GetList(object predicate = null, IList sort = null, bool buffered = false) where T : class { return DBSession.Connection.GetList(predicate, sort, null, null, buffered, databaseType: DBSession.DatabaseType) } /// /// Pagination /// /// /// /// /// /// /// /// /// public IEnumerable GetPageList(int pageIndex, int pageSize, out long allRowsCount, object predicate = null, IList sort = null, bool buffered = true) where T : class { if (sort == null) { sort = new List() } IEnumerable entityList = DBSession.Connection.GetPage(predicate, sort, pageIndex, pageSize, null, null, buffered, databaseType: DBSession.DatabaseType) allRowsCount = DBSession.Connection.Count(predicate, databaseType: DBSession.DatabaseType) return entityList } /// /// Insert a single record /// /// /// /// /// public dynamic Insert(T entity, IDbTransaction transaction = null) where T : class { dynamic result = DBSession.Connection.Insert(entity, transaction, databaseType: DBSession.DatabaseType) return result } /// /// Update a single record /// /// /// /// /// public bool Update(T entity, IDbTransaction transaction = null) where T : class { bool isOk = DBSession.Connection.Update(entity, transaction, databaseType: DBSession.DatabaseType) return isOk } /// /// delete a single record /// /// /// /// /// public int Delete(dynamic primaryId, IDbTransaction transaction = null) where T : class { var entity = GetById(primaryId) var obj = entity as T int isOk = DBSession.Connection.Delete(obj, databaseType: DBSession.DatabaseType) return isOk } /// /// delete a single record /// /// /// /// /// public int DeleteList(object predicate = null, IDbTransaction transaction = null) where T : class { return DBSession.Connection.Delete(predicate, transaction, databaseType: DBSession.DatabaseType) } /// /// Bulk insert function /// /// /// /// public bool InsertBatch(IEnumerable entityList, IDbTransaction transaction = null) where T : class { bool isOk = false foreach (var item in entityList) { Insert(item, transaction) } isOk = true return isOk } /// /// Batch update () /// /// /// /// /// public bool UpdateBatch(IEnumerable entityList, IDbTransaction transaction = null) where T : class { bool isOk = false foreach (var item in entityList) { Update(item, transaction) } isOk = true return isOk } /// /// batch deletion /// /// /// /// /// public bool DeleteBatch(IEnumerable ids, IDbTransaction transaction = null) where T : class { bool isOk = false foreach (var id in ids) { Delete(id, transaction) } isOk = true return isOk } } }

ORMは、ビッグデータの一括挿入を行うなどの万能薬ではなく、SqlHelperに加えて、DataTableやDataSetなどの一部の人々を必要とします。

したがって、基盤としてのSqlHelper、補助としてのORM、失うものは何もありません。

ORMの実装について話しましょう。以下のスクリーンショットを参照してください

IDataServiceRepository.cs(ビジネスレイヤーを使用するために提供され、内部のメソッドはSQLの転送をサポートしていません。SQLを含むステートメントは、データレイヤー操作に配置するのが最適です)

using System using System.Collections.Generic using System.Data using Dapper using DapperExtensions using HY.DataAccess namespace HY.ORM { /// /// Repository base class /// public class RepositoryBase : RepositoryServiceBase, IDataRepository { public RepositoryBase() { } public new void SetDBSession(IDBSession dbSession) { base.SetDBSession(dbSession) } public RepositoryBase(IDBSession dbSession) : base(dbSession) { } /// /// Filter out data collection based on criteria /// /// /// /// /// /// public IEnumerable Get(string sql, dynamic param = null, bool buffered = true) where T : class { return DBSession.Connection.Query(sql, param as object, DBSession.Transaction, buffered) } /// /// Filter data collection based on criteria /// /// /// /// /// public IEnumerable Get(string sql, dynamic param = null, bool buffered = true) { return DBSession.Connection.Query(sql, param as object, DBSession.Transaction, buffered) } /// /// Paging query /// /// /// /// /// /// /// /// /// /// /// public IEnumerable GetPage(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 entityList = DBSession.Connection.GetPage(pageIndex, pageSize, out allRowsCount, sql, param as object, allRowsCountSql, null, null, buffered, databaseType: DBSession.DatabaseType) return entityList } /// /// Filter by expression /// /// /// /// /// /// /// /// /// /// /// /// public IEnumerable Get(string sql, Func 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) } /// /// Filter by expression /// /// /// /// /// /// /// /// /// /// /// /// public IEnumerable Get(string sql, Func 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) } /// /// Get multiple entity collections /// /// /// /// /// /// /// 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) } /// /// Execute sql operation /// /// /// /// public int Execute(string sql, dynamic param = null, IDbTransaction transaction = null) { return DBSession.Connection.Execute(sql, param as object, transaction) } } }

IDataRepository.cs(データレイヤーの使用法を提供し、上記のIDataServiceRepositoryを継承し、着信SQLをサポートします)

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

RepositoryServiceBase.cs(IDataServiceRepository実装クラス)

Int xoID=666 //variable primary key using (IDbConnection conn = GetConnection()) { const string query = 'select * from XO where root@xxxxx' return conn.Query(query, new { MyID = xoID}) }

RepositoryBase.cs(IDataRepository実装クラス)

 / / entity class DemoEntity entity = new DemoEntity() / / According to the entity primary key delete this.Delete(entity) / / According to the primary key ID delete this.Delete(1) //increase this.Insert(entity) //update bool result = this.Update(entity) / / According to the primary key to return the entity entity = this.GetById(1) //Return the number of rows this.Count(new { ID = 1 }) //Query all IEnumerable list = this.GetAll() IList sort = new List() sort.Add(new Sort { PropertyName = 'ID', Ascending = false }) / / conditional query list = this.GetList(new { ID = 1, Name = '123' }, sort) //orm splicing condition query IList predList = new List() predList.Add(Predicates.Field(p => p.Name, Operator.Like, 'Don't know %')) predList.Add(Predicates.Field(p => p.ID, Operator.Eq, 1)) IPredicateGroup predGroup = Predicates.Group(GroupOperator.And, predList.ToArray()) list = this.GetList(predGroup) //Paging query long allRowsCount = 0 this.GetPageList(1, 10, out allRowsCount, new { ID = 1 }, sort)

DapperExtensionsが多くの小さな場所を変更したと言えば、次の図はコード比較のスクリーンショットです。そのため、しばらくの間コードを貼り付けます(記事の最後を参照)。

上記のコードはにコンパイルすることができます HY.ORM.DLL ファイルがなくなりました。

以下は、独自のビジネスレイヤーのHY.ORMのRepositoryServiceBaseクラスを継承でき、データレイヤーはHY.ORMのRepositoryBaseクラスを継承します。

データ接続の初期化は、それぞれのコンストラクターまたはSetDBSession(Helper.CreateDBSession())によって実行されます。

次に、エンティティクラスとDBのマッピングを構成します。

画像

|_+_|

画像

このようにして、this.Get( 'select * from Demo where root @ xxxxx'、new {ID = 1})をクラスに実装できます。

特定の用途

次の写真は、これから紹介するプロジェクトのスクリーンショットです。

実はこれも3層ですが、名前が違います。

HY.Web(UIレイヤー、MVC)

HY.Web.Iservice(サービスインターフェイスレイヤー)

HY.Web.Service(サービス層、HY.Web.Iservice実装クラス、ビジネスロジック層BLLとしても理解できます)

HY.Web.DAO(データアクセス層、DALも理解できます)

HY.Web.Entity(エンティティレイヤーは現在、データエンティティのみを定義します。システムがアプリにデータを提供する必要がある場合は、データを合理化する必要があります。DTOを個別に定義する必要があります。)

そのユーザーテーブルのインスタンスを作成しましょう。 テーブルの構造は次のとおりです(次の図はコードジェネレーターのスクリーンショット効果です。データベースの説明を直接変更し、武器を開発できます。ここに友達が必要です 【CodeBuilder-RazorEngine】 )。

HY.Web.Entity

HY.Web.Entityプロジェクトに新しいSys_UsersEntity.cs定義エンティティクラスを作成します

コードを見る

HY.Web.DAO

基本クラスBaseRepository.csを定義します(デフォルトのDBsessionを設定して、他のものを簡単に拡張できます)

コードを見る

データアクセス層Sys_UsersRepository.csを定義します(コードはSQLを記述する必要のあるすべてのコードをラップできます)

コードを見る

HY.Web.IService

UIへのアクセスを提供するために、インターフェースISys_UsersService.csを定義します。

コードを見る

HY.Web.Service

BaseService.csを定義します(デフォルトのDBsessionを設定して、他のものを簡単に拡張できます)

コードを見る

Sys_UsersService.csを定義して、ISys_UsersServiceを実装します。

コードを見る

HY.Web

1、関連するコントローラーを定義します

2、ISys_UsersService iSys_UsersService = new Sys_UsersService()(この部分は実際にIoC、関連コンテンツを使用し、その後の分解を聞くことができます)

3、インターフェースを呼び出す

コードを見る

ダウンロード

HY.DataAccess

変更されたDapperExtensions: Dapperextensions.RAR

PS:バージョンが更新され、ラムダに拡張機能が追加されました。クリックしてください ここに 入る