在自己研究ORM之前,也使用過幾個成熟的ORM方案,例如:EntityFramework,PetaPoco,Dapper 等,用是很好用,但是對自己來說總是不那么方便,EF比較笨重,Dapper要自定義擴展等等,所以萌發了開發適合自己的ORM的想法,因為未起名字,所以下文所有地方都使用MyORM來代替.
Nuget地址: https://www.nuget.org/packages/Dai.CommonLib.Sql
簡介: MyORM是一個小型的ORM,稍微參考了PetaPoco,支持簡單的對象關系映射,非常智能化,整個框架主要使用2個類型: QueryContext 和 DbQuery , 其中 DbQuery 只是一個高級的SqlHelper, 故下文主要介紹 QueryContext.
目前只支持 SqlServer 2005+ . Mysql的話以后再加上
1.一些特性
MyORM的映射關系主要是用Linq To Sql 自帶的2個特性來完成的 TableAttribute 和 ColumnAttribute
例:
[Table(Name="AlbumInfo")] public partial class AlbumInfo { [Column(Name="Id",IsPrimaryKey=true,IsDbGenerated=true)] public int Id { get; set; } [Column(Name="AlbumName")] public string AlbumName { get; set; } [Column(Name="CoverImg")] public string CoverImg { get; set; } [Column(Name="Desc")] public string Desc { get; set; } [Column(Name="Scope")] public int Scope { get; set; } [Column(Name="LookCount")] public int LookCount { get; set; } [Column(Name="PraiseCount")] public int PraiseCount { get; set; } [Column(Name="CommentCount")] public int CommentCount { get; set; } [Column(Name="CreatorId")] public int CreatorId { get; set; } [Column(Name="CreateTime")] public DateTime CreateTime { get; set; } [Column(Name="State")] public int State { get; set; } }
並且MyORM支持 MetadataTypeAttribute 特性
[MetadataType(typeof(MetadataTypeBase))] partial class AlbumInfo { } internal class MetadataTypeBase {
[System.Data.DeletedMapping(2)]
[System.Data.InvalidValue(2)]
[System.Data.ValidValue(0)]
[System.Data.ValidValue(1)]
public int State { get; set; } }
上面有幾個定義的特性:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace System.Data { /// <summary> /// 一個特性,用於標記數據刪除狀態 /// </summary> [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] public sealed class DeletedMappingAttribute : Attribute { public DeletedMappingAttribute(object value) { if (value == null || value == DBNull.Value) { throw new ArgumentNullException("值不能為null或DbNull.Value", "value"); } this.Value = value; } /// <summary> /// 獲取標記為刪除的值 /// </summary> public object Value { get; private set; } } }
//DeletedMappingAttribute 顧名思義,就是它用來標記一些並不需要真刪除的數據,后面介紹刪除的時候會用到.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace System.Data { /// <summary> /// 一個特性,用於標識數據字段數值的無效性 /// </summary> [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)] public sealed class InvalidValueAttribute : Attribute { public InvalidValueAttribute(object value) { //if (value == null || value == DBNull.Value) //{ // throw new ArgumentNullException("值不能為null或DbNull.Value", "value"); //} this.Value = value; } /// <summary> /// 獲取字段的無效值 /// </summary> public object Value { get; private set; } } }
//這個特性主要用於根據主鍵查詢數據,它會自動過濾掉不符合條件的數據,簡化我們編碼
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace System.Data { /// <summary> /// 一個特性,用於標識數據字段數值的有效性 /// </summary> [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)] public sealed class ValidValueAttribute : Attribute { public ValidValueAttribute(object value) { //if (value == null || value == DBNull.Value) //{ // throw new ArgumentNullException("值不能為null或DbNull.Value", "value"); //} this.Value = value; } /// <summary> /// 獲取字段的有效值 /// </summary> public object Value { get; private set; } } }
//這個特性主要用於根據主鍵查詢數據,它會自動匹符合條件的數據,簡化我們編碼
2.開始使用:
表 AlbumInfo:

使用QueryContext前先初始化:
protected QueryContext QueryContext = new QueryContext("DBConnectionString");
插入一條數據:
[TestMethod] public void InsertTest() { AlbumInfo album = new AlbumInfo() { AlbumName = "測試", CreateTime = DateTime.Now, CreatorId = -1, Desc = "測試相冊", Scope = 1, }; QueryContext.Insert(album); Assert.IsTrue(album.Id > 0); }
查詢:
QueryContext 提供了多種查詢的方式:
(1).根據主鍵查:
var album = QueryContext.ByPrimaryKey<AlbumInfo>(2);
注意這里有個重載
var album = QueryContext.ByPrimaryKey<AlbumInfo>(2,true);
他們之間的區別就是上面 ValidValueAttribute 和InvalidValueAttribute 介紹的,附帶查詢條件的區別
假設我給AlbumInfo的字段 State 設置的無效類型是 2 (刪除狀態),那么第一種方法查出來是null,第二種查出來才有值
有個泛型重載方法可以簡單的將查詢出來的數據轉換成Dto
var albumDto = QueryContext.ByPrimaryKey<AlbumInfo,AlbumInfoDto>(2);
查詢指定類型:
// // 摘要: // 查詢指定數據 // // 參數: // sql: // // args: // // 類型參數: // T: public List<T> Fetch<T>(string sql, params object[] args);
sql可以是這種寫法 : select * from albuminfo where ........,也可以精簡為 where ..... ,程序會自動判斷填充的,甚至可以這樣:
QueryContext.Fetch<AlbumInfo>("");
它支持參數查詢(PetaPoco),可以這樣:
QueryContext.Fetch<AlbumInfo>("where id>@0 and createid=@1",1,-1);
也可以這樣
var createTimePar=QueryContext.CreateParameter("createtime",DateTime.Now); QueryContext.Fetch<AlbumInfo>("where id>@0 and createtime>@createtime and createid=@1",1,createTimePar,-1);
Fetch方法支持簡單類型的查詢:
QueryContext.Fetch<int>("Select id From AlbumInfo");
如果你不確定返回的是什么類型,可以使用這個重載,它會自動填充的
// // 摘要: // 查詢數據 // // 參數: // sql: // // args: public List<dynamic> Fetch(string sql, params object[] args);
Fetch方法有個重載:
// // 摘要: // 查詢指定數據 // // 參數: // sql: // // args: // // 類型參數: // TTable: // 要查詢的數據表類型 // // TResult: // 返回結果類型 public List<TResult> Fetch<TTable, TResult>(string sql, params object[] args)
可以返回需要的類型
List<AlbumInfoDto> list= QueryContext.Fetch<AlbumInfo,AlbumInfoDto>("");
Fetch方法有個延遲加載版本 Query ,與Fetch類似
分頁: QueryContext支持簡單的分頁
// // 摘要: // 查詢分頁數據 // // 參數: // page: // // pageSize: // // sql: // // args: // // 類型參數: // T: public IPageResult<T> Page<T>(int page, int pageSize, string sql, params object[] args); // // 摘要: // 查詢分頁數據 // // 參數: // page: // // pageSize: // // sql: // // args: public IPageResult<dynamic> Page(int page, int pageSize, string sql, params object[] args); // // 摘要: // 異步查詢分頁 // // 參數: // page: // // pageSize: // // sql: // // args: // // 類型參數: // T: [DebuggerStepThrough] public Task<IPageResult<T>> PageAsync<T>(int page, int pageSize, string sql, params object[] args); // // 摘要: // 異步查詢分頁 // // 參數: // page: // // pageSize: // // sql: // // args: // // 類型參數: // TTable: // 要查詢的數據表類型 // // TResult: // 返回結果類型 [DebuggerStepThrough] public Task<IPageResult<TResult>> PageAsync<TTable, TResult>(int page, int pageSize, string sql, params object[] args) where TTable : class where TResult : class; // // 摘要: // 異步查詢分頁 // // 參數: // page: // // pageSize: // // sql: // // args: [DebuggerStepThrough] public Task<IPageResult<dynamic>> PageAsync(int page, int pageSize, string sql, params object[] args);
這么用:
QueryContext.Page<AlbumInfo>(1,10,"where id>@0",1);
它返回一個IPageResult類型的數據
using System.Collections; using System.Collections.Generic; namespace System { // 摘要: // 一個接口,表示一個分頁結果集 // // 類型參數: // T: public interface IPageResult<out T> : IPageResult, IEnumerable<T>, IEnumerable { } } using System.Collections; namespace System { // 摘要: // 一個接口,表示一個分頁結果集 public interface IPageResult : IEnumerable { // 摘要: // 獲取當前集合的數量 int Count { get; } // // 摘要: // 獲取當前頁碼 int CurrentPage { get; } // // 摘要: // 每頁顯示數 int ItemsPerPage { get; } // // 摘要: // 獲取數據總數 long TotalItems { get; } // // 摘要: // 獲取分頁總數 int TotalPages { get; } } }
分頁也與上面一樣,有各種重載方法
FirstOrDefault:
如果查詢單條數據就使用它:
// // 摘要: // 查詢第一條數據 // // 參數: // sql: // // args: // // 類型參數: // T: public TResult FirstOrDefault<TTable, TResult>(string sql, params object[] args) where TTable : class where TResult : class; // // 摘要: // 查詢第一條數據 // // 參數: // sql: // // args: // // 類型參數: // T: public T FirstOrDefault<T>(string sql, params object[] args); // // 摘要: // 查詢第一條數據 // // 參數: // sql: // // args: public dynamic FirstOrDefault(string sql, params object[] args);
存儲過程:
查詢的方法都有存儲過程版本,方法名多一個"Procedure":
// // 摘要: // 調用存儲過程查詢指定數據 // // 參數: // procedureName: // // args: // // 類型參數: // T: public List<T> FetchProcedure<T>(string procedureName, params object[] args);
更新:
var album = QueryContext.ByPrimaryKey<AlbumInfo>(2); Assert.IsNotNull(album); album.AlbumName = "修改過的測試"; album.Desc = "修改過的測試相冊"; //var result = QueryContext.Update(album); //var result = QueryContext.Update(album, "AlbumName", "Desc"); var result = QueryContext.Update(album, o => o.AlbumName, o => o.Desc); Assert.IsTrue(result); var newAlbum = QueryContext.ByPrimaryKey<AlbumInfo>(album.Id); Assert.IsTrue(newAlbum.AlbumName.Equals(album.AlbumName)); Assert.IsTrue(newAlbum.Desc.Equals(album.Desc));
更新可以完整更新,也可以約定更新字段,並且支持指定字段名和使用對象映射字段
刪除:
var album = QueryContext.ByPrimaryKey<AlbumInfo>(2); QueryContext.Delete(album); Assert.IsNull(QueryContext.ByPrimaryKey<AlbumInfo>(2)); Assert.IsNotNull(QueryContext.ByPrimaryKey<AlbumInfo>(2, true)); album = QueryContext.ByPrimaryKey<AlbumInfo>(2, true); album.State = 0; album.CoverImg = ""; QueryContext.Update(album, o => o.State, o => o.CoverImg); album = QueryContext.ByPrimaryKey<AlbumInfo>(2); QueryContext.Delete(album, true); Assert.IsNull(QueryContext.ByPrimaryKey<AlbumInfo>(2)); Assert.IsNull(QueryContext.ByPrimaryKey<AlbumInfo>(2, true));
刪除有2種,一種是刪除數據,一種是修改刪除狀態(需要使用前面提到的System.Data.DeletedMapping來約定條件)
事務:
QueryContext支持簡單的事務
// // 摘要: // 啟動事務 // // 參數: // context: public void Transaction(Action<IQueryContext> action); // // 摘要: // 啟動事務 // // 參數: // context: public void Transaction(IsolationLevel isolationLevel, Action<IQueryContext> action);
var album = QueryContext.ByPrimaryKey<AlbumInfo>(2); var albumDto = QueryContext.ByPrimaryKey<AlbumInfo, AlbumInfoDto>(2); QueryContext.Transaction(context => { album.AlbumName = "修改過的事務"; context.Update(album, "AlbumName"); }); string albumName = QueryContext.ExecuteScalar<string>("Select AlbumName From AlbumInfo Where ID=@0", 2); Assert.AreEqual(album.AlbumName, albumName); try { QueryContext.Transaction(context => { album.AlbumName = "修改回來的事務"; context.Update(album, "AlbumName"); throw new Exception(); }); } catch { } albumName = QueryContext.ExecuteScalar<string>("Select AlbumName From AlbumInfo Where ID=@0", 2); Assert.AreNotEqual(album.AlbumName, albumName);
在事務的執行過程中,如果不發生錯誤,則執行完之后會提交事務,如果發生錯誤,則回滾,同時將錯誤繼續向上級拋,所以如果要手動控制流程的話,就拋出個異常吧!
以上就是QueryContext的一個簡單介紹,而MyORM的核心就是QueryContext!
using System; namespace System.Data { // 摘要: // 數據查詢上下文,支持映射實體的操作(使用默認設置) public sealed class QueryContext : QueryContextBase { public QueryContext(); public QueryContext(string connectionStringName); public static string DefaultConnectionStringName { get; set; } } } using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq.Expressions; using System.Threading.Tasks; namespace System.Data { // 摘要: // 數據查詢上下文,支持映射實體的操作 public abstract class QueryContextBase : DbQueryMethod, IQueryContext, IAsyncQueryContext, IDisposable { protected QueryContextBase(string connectionStringName); // 摘要: // 根據主鍵獲取數據(可使用 System.Data.ValidValueAttribute 來約定條件) // // 參數: // primaryValue: // // 類型參數: // T: public T ByPrimaryKey<T>(object primaryValue) where T : class; // // 摘要: // 根據主鍵獲取數據(可使用 System.Data.ValidValueAttribute 來約定條件) // // 參數: // primaryValue: // // 類型參數: // TTable: // 要查詢的數據表類型 // // TResult: // 返回結果類型 public TResult ByPrimaryKey<TTable, TResult>(object primaryValue) where TTable : class where TResult : class; // // 摘要: // 根據主鍵獲取數據,並指定是否忽略約束條件 // // 參數: // primaryValue: // // ignore: // // 類型參數: // T: public T ByPrimaryKey<T>(object primaryValue, bool ignore) where T : class; // // 摘要: // 根據主鍵獲取數據,並指定是否忽略約束條件 // // 參數: // primaryValue: // // ignore: // // 類型參數: // TTable: // 要查詢的數據表類型 // // TResult: // 返回結果類型 public TResult ByPrimaryKey<TTable, TResult>(object primaryValue, bool ignore) where TTable : class where TResult : class; // // 摘要: // 異步根據主鍵獲取數據(可使用 System.Data.ValidValueAttribute 來約定條件) // // 參數: // primaryValue: // // 類型參數: // T: [DebuggerStepThrough] public Task<T> ByPrimaryKeyAsync<T>(object primaryValue) where T : class; // // 摘要: // 異步根據主鍵獲取數據(可使用 System.Data.ValidValueAttribute 來約定條件) // // 參數: // primaryValue: // // 類型參數: // TTable: // 要查詢的數據表類型 // // TResult: // 返回結果類型 [DebuggerStepThrough] public Task<TResult> ByPrimaryKeyAsync<TTable, TResult>(object primaryValue) where TTable : class where TResult : class; // // 摘要: // 異步根據主鍵獲取數據,並指定是否忽略約束條件 // // 參數: // primaryValue: // // ignore: // // 類型參數: // T: [DebuggerStepThrough] public Task<T> ByPrimaryKeyAsync<T>(object primaryValue, bool ignore) where T : class; // // 摘要: // 異步根據主鍵獲取數據,並指定是否忽略約束條件 // // 參數: // primaryValue: // // ignore: // // 類型參數: // TTable: // 要查詢的數據表類型 // // TResult: // 返回結果類型 [DebuggerStepThrough] public Task<TResult> ByPrimaryKeyAsync<TTable, TResult>(object primaryValue, bool ignore) where TTable : class where TResult : class; // // 摘要: // 基於當前提供的驅動程序創建一個System.Data.DbParameter // // 參數: // parameterName: // // value: public IDbDataParameter CreateParameter(string parameterName, object value); // // 摘要: // 基於當前提供的驅動程序創建一個System.Data.DbParameter,並指定System.Data.DbParameter參數類型 // // 參數: // parameterName: // // value: // // direction: public IDbDataParameter CreateParameter(string parameterName, object value, ParameterDirection direction); // // 摘要: // 根據主鍵刪除實體(可用 System.Data.DeletedMappingAttribute 控制刪除還是修改刪除狀態) // // 參數: // entity: // // 類型參數: // T: public bool Delete<T>(T entity) where T : class; // // 摘要: // 根據主鍵刪除實體,一個參數指示是否忽略 System.Data.DeletedMappingAttribute 屬性 // // 參數: // entity: // // ignoreDeletedMappingAttribute: // // 類型參數: // T: public bool Delete<T>(T entity, bool ignoreDeletedMappingAttribute) where T : class; // // 摘要: // 異步根據主鍵刪除實體(可用 System.Data.DeletedMappingAttribute 控制刪除還是修改刪除狀態) // // 參數: // entity: // // 類型參數: // T: [DebuggerStepThrough] public Task<bool> DeleteAsync<T>(T entity) where T : class; // // 摘要: // 異步根據主鍵刪除實體,一個參數指示是否忽略 System.Data.DeletedMappingAttribute 屬性 // // 參數: // entity: // // 類型參數: // T: [DebuggerStepThrough] public Task<bool> DeleteAsync<T>(T entity, bool ignoreDeletedMappingAttribute) where T : class; // // 摘要: // 執行Sql // // 參數: // sql: // // args: public int Execute(string sql, params object[] args); // // 摘要: // 異步執行Sql // // 參數: // sql: // // args: [DebuggerStepThrough] public Task<int> ExecuteAsync(string sql, params object[] args); // // 摘要: // 執行存儲過程 // // 參數: // procedureName: // // args: public int ExecuteProcedure(string procedureName, params object[] args); // // 摘要: // 異步執行存儲過程 // // 參數: // procedureName: // // args: [DebuggerStepThrough] public Task<int> ExecuteProcedureAsync(string procedureName, params object[] args); // // 摘要: // 執行查詢,並返回查詢所返回的結果集中第一行的第一列。 所有其他的列和行將被忽略。 // // 參數: // sql: // // args: public object ExecuteScalar(string sql, params object[] args); // // 摘要: // 執行查詢,並返回查詢所返回的結果集中第一行的第一列。 所有其他的列和行將被忽略。 // // 參數: // sql: // // args: // // 類型參數: // T: public T ExecuteScalar<T>(string sql, params object[] args); // // 摘要: // 異步執行查詢,並返回查詢所返回的結果集中第一行的第一列。 所有其他的列和行將被忽略。 // // 參數: // sql: // // args: // // 類型參數: // T: [DebuggerStepThrough] public Task<T> ExecuteScalarAsync<T>(string sql, params object[] args); // // 摘要: // 異步執行查詢,並返回查詢所返回的結果集中第一行的第一列。 所有其他的列和行將被忽略。 // // 參數: // sql: // // args: [DebuggerStepThrough] public Task<object> ExecuteScalarAsync(string sql, params object[] args); // // 摘要: // 執行查詢存儲過程,並返回查詢所返回的結果集中第一行的第一列。 所有其他的列和行將被忽略。 // // 參數: // procedureName: // // args: // // 類型參數: // T: public T ExecuteScalarProcedure<T>(string procedureName, params object[] args); // // 摘要: // 執行查詢存儲過程,並返回查詢所返回的結果集中第一行的第一列。 所有其他的列和行將被忽略。 // // 參數: // procedureName: // // args: public object ExecuteScalarProcedure(string procedureName, params object[] args); // // 摘要: // 異步執行查詢存儲過程,並返回查詢所返回的結果集中第一行的第一列。 所有其他的列和行將被忽略。 // // 參數: // procedureName: // // args: [DebuggerStepThrough] public Task<object> ExecuteScalarProcedureAsync(string procedureName, params object[] args); // // 摘要: // 異步執行查詢存儲過程,並返回查詢所返回的結果集中第一行的第一列。 所有其他的列和行將被忽略。 // // 參數: // procedureName: // // args: // // 類型參數: // T: [DebuggerStepThrough] public Task<T> ExecuteScalarProcedureAsync<T>(string procedureName, params object[] args); // // 摘要: // 查詢指定數據 // // 參數: // sql: // // args: // // 類型參數: // T: public List<T> Fetch<T>(string sql, params object[] args); // // 摘要: // 查詢指定數據 // // 參數: // sql: // // args: // // 類型參數: // TTable: // 要查詢的數據表類型 // // TResult: // 返回結果類型 public List<TResult> Fetch<TTable, TResult>(string sql, params object[] args) where TTable : class where TResult : class; // // 摘要: // 查詢數據 // // 參數: // sql: // // args: public List<dynamic> Fetch(string sql, params object[] args); // // 摘要: // 異步查詢指定數據 // // 參數: // sql: // // args: // // 類型參數: // TTable: // 要查詢的數據表類型 // // TResult: // 返回結果類型 [DebuggerStepThrough] public Task<List<TResult>> FetchAsync<TTable, TResult>(string sql, params object[] args) where TTable : class where TResult : class; // // 摘要: // 異步查詢指定數據 // // 參數: // sql: // // args: // // 類型參數: // T: [DebuggerStepThrough] public Task<List<T>> FetchAsync<T>(string sql, params object[] args); // // 摘要: // 異步查詢數據 // // 參數: // sql: // // args: // // 類型參數: // T: [DebuggerStepThrough] public Task<List<dynamic>> FetchAsync(string sql, params object[] args); // // 摘要: // 調用存儲過程查詢指定數據 // // 參數: // procedureName: // // args: // // 類型參數: // T: public List<T> FetchProcedure<T>(string procedureName, params object[] args); // // 摘要: // 調用存儲過程查詢數據 // // 參數: // procedureName: // // args: public List<dynamic> FetchProcedure(string procedureName, params object[] args); // // 摘要: // 調用存儲過程異步查詢指定數據 // // 參數: // sql: // // args: // // 類型參數: // T: [DebuggerStepThrough] public Task<List<T>> FetchProcedureAsync<T>(string procedureName, params object[] args); // // 摘要: // 調用存儲過程異步查詢數據 // // 參數: // sql: // // args: // // 類型參數: // T: [DebuggerStepThrough] public Task<List<dynamic>> FetchProcedureAsync(string procedureName, params object[] args); // // 摘要: // 查詢第一條數據 // // 參數: // sql: // // args: // // 類型參數: // T: public TResult FirstOrDefault<TTable, TResult>(string sql, params object[] args) where TTable : class where TResult : class; // // 摘要: // 查詢第一條數據 // // 參數: // sql: // // args: // // 類型參數: // T: public T FirstOrDefault<T>(string sql, params object[] args); // // 摘要: // 查詢第一條數據 // // 參數: // sql: // // args: public dynamic FirstOrDefault(string sql, params object[] args); // // 摘要: // 異步查詢第一條數據 // // 參數: // sql: // // args: // // 類型參數: // T: [DebuggerStepThrough] public Task<T> FirstOrDefaultAsync<T>(string sql, params object[] args); // // 摘要: // 異步查詢第一條數據 // // 參數: // sql: // // args: // // 類型參數: // T: [DebuggerStepThrough] public Task<dynamic> FirstOrDefaultAsync(string sql, params object[] args); // // 摘要: // 異步查詢第一條數據 // // 參數: // sql: // // args: // // 類型參數: // TTable: // 要查詢的數據表類型 // // TResult: // 返回結果類型 [DebuggerStepThrough] public Task<TResult> FirstOrDefaultAsync<TTable, TResult>(string sql, params object[] args) where TTable : class where TResult : class; // // 摘要: // 查詢第一條數據 // // 參數: // procedureName: // // args: // // 類型參數: // T: public T FirstOrDefaultProcedure<T>(string procedureName, params object[] args); // // 摘要: // 查詢第一條數據 // // 參數: // procedureName: // // args: public dynamic FirstOrDefaultProcedure(string procedureName, params object[] args); // // 摘要: // 調用存儲過程異步查詢第一條數據 // // 參數: // procedureName: // // args: // // 類型參數: // T: [DebuggerStepThrough] public Task<T> FirstOrDefaultProcedureAsync<T>(string procedureName, params object[] args); // // 摘要: // 調用存儲過程異步查詢第一條數據 // // 參數: // procedureName: // // args: // // 類型參數: // T: [DebuggerStepThrough] public Task<dynamic> FirstOrDefaultProcedureAsync(string procedureName, params object[] args); // // 摘要: // 得到表列 // // 類型參數: // T: public string[] GetColumns<T>() where T : class; // // 摘要: // 得到表列 // // 類型參數: // T: public static string[] GetColumns<T>(string connectionStringName); // // 摘要: // 獲取查詢表列Sql // // 類型參數: // T: public string GetColumnsString<T>() where T : class; // // 摘要: // 將映射實體插入數據庫 // // 參數: // entity: // // 類型參數: // T: public object Insert<T>(T entity) where T : class; // // 摘要: // 異步將映射實體插入數據庫 // // 參數: // entity: // // 類型參數: // T: [DebuggerStepThrough] public Task<object> InsertAsync<T>(T entity) where T : class; // // 摘要: // 查詢分頁數據 // // 參數: // page: // // pageSize: // // sql: // // args: // // 類型參數: // TTable: // 要查詢的數據表類型 // // TResult: // 返回結果類型 public IPageResult<TResult> Page<TTable, TResult>(int page, int pageSize, string sql, params object[] args) where TTable : class where TResult : class; // // 摘要: // 查詢分頁數據 // // 參數: // page: // // pageSize: // // sql: // // args: // // 類型參數: // T: public IPageResult<T> Page<T>(int page, int pageSize, string sql, params object[] args); // // 摘要: // 查詢分頁數據 // // 參數: // page: // // pageSize: // // sql: // // args: public IPageResult<dynamic> Page(int page, int pageSize, string sql, params object[] args); // // 摘要: // 異步查詢分頁 // // 參數: // page: // // pageSize: // // sql: // // args: // // 類型參數: // T: [DebuggerStepThrough] public Task<IPageResult<T>> PageAsync<T>(int page, int pageSize, string sql, params object[] args); // // 摘要: // 異步查詢分頁 // // 參數: // page: // // pageSize: // // sql: // // args: // // 類型參數: // TTable: // 要查詢的數據表類型 // // TResult: // 返回結果類型 [DebuggerStepThrough] public Task<IPageResult<TResult>> PageAsync<TTable, TResult>(int page, int pageSize, string sql, params object[] args) where TTable : class where TResult : class; // // 摘要: // 異步查詢分頁 // // 參數: // page: // // pageSize: // // sql: // // args: [DebuggerStepThrough] public Task<IPageResult<dynamic>> PageAsync(int page, int pageSize, string sql, params object[] args); // // 摘要: // 查詢指定數據 // // 參數: // sql: // // pars: // // 類型參數: // T: public IEnumerable<T> Query<T>(string sql, params object[] args); // // 摘要: // 查詢數據 // // 參數: // sql: // // pars: public IEnumerable<dynamic> Query(string sql, params object[] args); // // 摘要: // 查詢指定數據 // // 參數: // sql: // // pars: // // 類型參數: // TTable: // 要查詢的數據表類型 // // TResult: // 返回結果類型 public IEnumerable<TResult> Query<TTable, TResult>(string sql, params object[] args) where TTable : class where TResult : class; // // 摘要: // 調用存儲過程查詢指定數據 // // 參數: // sql: // // pars: // // 類型參數: // T: public IEnumerable<T> QueryProcedure<T>(string procedureName, params object[] args); // // 摘要: // 調用存儲過程查詢數據 // // 參數: // sql: // // pars: // // 類型參數: // T: public IEnumerable<dynamic> QueryProcedure(string procedureName, params object[] args); // // 摘要: // 啟動事務 // // 參數: // context: public void Transaction(Action<IQueryContext> action); // // 摘要: // 啟動事務 // // 參數: // context: public void Transaction(IsolationLevel isolationLevel, Action<IQueryContext> action); // // 摘要: // 啟動異步事務 // // 參數: // action: [DebuggerStepThrough] public Task TransactionAsync(Func<IAsyncQueryContext, Task> action); // // 摘要: // 啟動異步事務 // // 參數: // action: [DebuggerStepThrough] public Task TransactionAsync(IsolationLevel isolationLevel, Func<IAsyncQueryContext, Task> action); // // 摘要: // 將映射實體更新到數據庫中 // // 參數: // entity: // // properties: // 指定的屬性 // // 類型參數: // T: public bool Update<T>(T entity, params Expression<Func<T, object>>[] properties) where T : class; // // 摘要: // 將映射實體更新到數據庫中 // // 參數: // entity: // // columns: // 暫不支持 // // 類型參數: // T: public bool Update<T>(T entity, params string[] columns) where T : class; // // 摘要: // 異步將映射實體更新到數據庫中 // // 參數: // entity: // // properties: // 指定的屬性 // // 類型參數: // T: [DebuggerStepThrough] public Task<bool> UpdateAsync<T>(T entity, params Expression<Func<T, object>>[] properties) where T : class; // // 摘要: // 異步將映射實體更新到數據庫中 // // 參數: // entity: // // columns: // // 類型參數: // T: [DebuggerStepThrough] public Task<bool> UpdateAsync<T>(T entity, params string[] columns) where T : class; } }
性能方面,QueryContext內部使用Expression生成委托,並緩存委托的方式,因此性能不會差到哪去,比反射肯定是好的.
關於MyORM相關的簡單介紹就先告一段落了,近期有時間的話,我會把一些主要的結構,想法,代碼介紹一下.
