• 自制简单的.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相关的简单介绍就先告一段落了,近期有时间的话,我会把一些主要的结构,想法,代码介绍一下.

  • 相关阅读:
    C#_Assembly-Reflection_程序集与反射
    C#_event_事件
    C#_扩展方法
    C#_Delegate_泛型
    C#_正则表达式
    C#_序列化
    Unity_ClickToShow_FadeInAndOut
    RecordToday
    写作技巧
    高效休息法
  • 原文地址:https://www.cnblogs.com/pokemon/p/5198591.html
Copyright © 2020-2023  润新知