自制簡單的.Net ORM框架 (一) 簡介


   在自己研究ORM之前,也使用過幾個成熟的ORM方案,例如:EntityFramework,PetaPoco,Dapper 等,用是很好用,但是對自己來說總是不那么方便,EF比較笨重,Dapper要自定義擴展等等,所以萌發了開發適合自己的ORM的想法,因為未起名字,所以下文所有地方都使用MyORM來代替.

 

Nuget地址: https://www.nuget.org/packages/Dai.CommonLib.Sql

 

簡介: MyORM是一個小型的ORM,稍微參考了PetaPoco,支持簡單的對象關系映射,非常智能化,整個框架主要使用2個類型: QueryContextDbQuery , 其中 DbQuery 只是一個高級的SqlHelper, 故下文主要介紹 QueryContext.

目前只支持 SqlServer 2005+ .   Mysql的話以后再加上 

 

1.一些特性

MyORM的映射關系主要是用Linq To Sql 自帶的2個特性來完成的 TableAttributeColumnAttribute 

例: 

[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;
    }
}
View Code

 

性能方面,QueryContext內部使用Expression生成委托,並緩存委托的方式,因此性能不會差到哪去,比反射肯定是好的.

 

 

關於MyORM相關的簡單介紹就先告一段落了,近期有時間的話,我會把一些主要的結構,想法,代碼介紹一下.


免責聲明!

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



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