asp.net泛型结合反射的简单Base封装

泛型(generic)是C#语言2.0和通用语言运行时(CLR)的一个新特性。泛型为.NET框架引入了类型参数(type parameters)的概念。类型参数使得设计类和方法时,不必确定一个或多个具体参数,其的具体参数可延迟到客户代码中声明、实现。这意味着使用泛型的类型参数T,写一个类MyList<T>,客户代码可以这样调用:MyList<int>, MyList<string>或 MyList<MyClass>。这避免了运行时类型转换或装箱操作的代价和风险。

这应该是微软干的一件大好事,关于 T 这个类型,要说的就太多了。在编译时会生成一个`1【相对于一个参数的时候,多个会生成对应的占位符】的占位符,就是说,这个类型参数不确定但是我又具体不知道现在这个参数类型到底是什么类的。那好,我不确定我就先把你放一个占位子的东西放到,在我调用的时候我在传进来。

关于泛型的约束

//指定GenericMethod方法用以执行类型为X的参数
        public T GenericMethod<T>(T t)
        {
            return default(T);
        }
//泛型方法的泛型参数的约束
 public void GenericMethod<T>(T t) where T:IComparable<X>
        {
            //
        }
//泛型类的约束, T必须有一个无参的构造函数
 public class GenericClass<T> where T: new()
    {

    }

//结构体约束
  public class GenericClass<T>where T : struct
{

}

下表列出了五类约束:


约束


描述


where T: struct


类型参数必须为值类型。


where T : class


类型参数必须为引用类型。


where T : new()


类型参数必须有一个公有、无参的构造函数。当于其它约束联合使用时,new()约束必须放在最后。


where T : <base class name>


类型参数必须是指定的基类型或是派生自指定的基类型。


where T : <interface name>


类型参数必须是指定的接口或是指定接口的实现。可以指定多个接口约束。接口约束也可以是泛型的。

类型参数的约束,增加了可调用的操作和方法的数量。这些操作和方法受约束类型及其派生层次中的类型的支持。因此,设计泛型类或方法时,如果对泛型成员执行任何赋值以外的操作,或者是调用System.Object中所没有的方法,就需要在类型参数上使用约束。

无限制类型参数的一般用法

没有约束的类型参数,如公有类MyClass<T>{...}中的T, 被称为无限制类型参数(unbounded type parameters)。无限制类型参数有以下规则:

l        不能使用运算符 != 和 == ,因为无法保证具体的类型参数能够支持这些运算符。

l        它们可以与System.Object相互转换,也可显式地转换成任何接口类型。

l        可以与null比较。如果一个无限制类型参数与null比较,当此类型参数为值类型时,比较的结果总为false。

无类型约束

当约束是一个泛型类型参数时,它就叫无类型约束(Naked type constraints)。当一个有类型参数成员方法,要把它的参数约束为其所在类的类型参数时,无类型约束很有用。如下例所示:

class List<T>

{

//...

void Add<U>(List<U> items) where U:T {…}

}

在上面的示例中, Add方法的上下文中的T,就是一个无类型约束;而List类的上下文中的T,则是一个无限制类型参数。

无类型约束也可以用在泛型类的定义中。注意,无类型约束一定也要和其它类型参数一起在尖括号中声明:

//naked type constraint

public class MyClass<T,U,V> where T : V

因为编译器只认为无类型约束是从System.Object继承而来,所以带有无类型约束的泛型类的用途十分有限。当你希望强制两个类型参数具有继承关系时,可对泛型类使用无类型约束。

泛型类

泛型类封装了不针对任何特定数据类型的操作。泛型类常用于容器类,如链表、哈希表、栈、队列、树等等。这些类中的操作,如对容器添加、删除元素,不论所存储的数据是何种类型,都执行几乎同样的操作。

对大多数情况,推荐使用.NET框架2.0类库中所提供的容器类。有关使用这些类的详细信息,请参见基础类库中的泛型。

通常,从一个已有的具体类来创建泛型类,并每次把一个类型改为类型参数,直至达到一般性和可用性的最佳平衡。当创建你自己的泛型类时,需要重点考虑的事项有:

l        哪些类型应泛化为类型参数。一般的规律是,用参数表示的类型越多,代码的灵活性和复用性也就越大。过多的泛化会导致代码难以被其它的开发人员理解。

l        如果有约束,那么类型参数需要什么样约束。一个良好的习惯是,尽可能使用最大的约束,同时保证可以处理所有需要处理的类型。例如,如果你知道你的泛型类只打算使用引用类型,那么就应用这个类的约束。这样可以防止无意中使用值类型,同时可以对T使用as运算符,并且检查空引用。

l        把泛型行为放在基类中还是子类中。泛型类可以做基类。同样非泛型类的设计中也应考虑这一点。泛型基类的继承规则     。

l        是否实现一个或多个泛型接口。例如,要设计一个在基于泛型的容器中创建元素的类,可能需要实现类似IComparable<T>的接口,其中T是该类的参数。

泛型概述中有一个简单泛型类的例子。

类型参数和约束的规则对于泛型类的行为(behavior)有一些潜在的影响,——尤其是对于继承和成员可访问性。在说明这个问题前,理解一些术语十分重要。对于一个泛型类Node<T>,客户代码既可以通过指定一个类型参数来创建一个封闭构造类型(Node<int>),也可以保留类型参数未指定,例如指定一个泛型基类来创建开放构造类型(Node<T>)。泛型类可以继承自具体类、封闭构造类型或开放构造类型

// concrete type
class Node<T> : BaseNode
//closed constructed type
class Node<T> : BaseNode<int>
//open constructed type
class Node<T> : BaseNode<T>

非泛型的具体类可以继承自封闭构造基类,但不能继承自开放构造基类。这是因为客户代码无法提供基类所需的类型参数。

//No error.
class Node : BaseNode<int>
//Generates an error.
class Node : BaseNode<T>

泛型的具体类可以继承自开放构造类型。除了与子类共用的类型参数外,必须为所有的类型参数指定类型,如下代码所示:

//错误.
class Node<T> : BaseNode<T, U> {…}
//正确.
class Node<T> : BaseNode<T, int>{…}
 

继承自开放结构类型的泛型类,必须指定:

class NodeItem<T> where T : IComparable<T>, new() {…}
class MyNodeItem<T> : NodeItem<T> where T : IComparable<T> , new(){…}

泛型类型可以使用多种类型参数和约束,如下:

class KeyType<K,V>{…}
class SuperKeyType<K,V,U> where U : IComparable<U>, where V : new(){…}

泛型接口

不论是为泛型容器类,还是表示容器中元素的泛型类,定义接口是很有用的。把泛型接口与泛型类结合使用是更好的用法,比如用IComparable<T>而非IComparable,以避免值类型上的装箱和拆箱操作。.NET框架2.0类库定义了几个新的泛型接口,以配合System.Collections.Generic中新容器类的使用。

 public interface BaseIDAL<T> where T : new()
 public partial interface UserIDAL : BaseIDAL<Model.User>

嗯!代码整体结构如下,不管是三层还是MVC,我觉得都一样。我这里就简单的用控制台演示一下调用就可以。只有用法,仁者见仁智者见智

我这里是为了完整搭建完整的框架而已。所有就建立了这么多类库,LambdaAndGeneric.Common,和LambdaAndGeneric.FactoryDAL暂时还没用到。你们可以不用跟着建。

首先新建7个类库,版本我就不多说了!!!!

话不多说。上代码。

1、首先在 LamdbaAndGeneric.HelperDAL类库下新建一个类

名称:SenctionHelper.cs代码如下注意引用一下System.Configuration这个dll动态库

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LamdbaAndGeneric.HelperDAL
{
    public static class SenctionHelper
    {

        static string ConnectionStringCustomers;

        static SenctionHelper()
        {
            ConnectionStringCustomers = ConfigurationManager.ConnectionStrings["Customers"].ConnectionString;

        }

        #region 公用

        #region 获取映射模型的字段
        /// <summary>
        /// 获得当前对象的所有公共字段
        /// </summary>
        /// <param name="modelName"></param>
        /// <returns></returns>
        public static string GetModelSenction<T>()
        {
            Type type = typeof(T);
            return string.Join(",", type.GetProperties().Select(p => string.Format("[{0}]", p.Name)));
        }
        #endregion

        #region ExecuteNonQuery +static int ExecuteNonQuery(string cmdText, params SqlParameter[] parameters)
        /// <summary>
        /// 执行一个非查询的T-SQL语句,返回受影响行数,如果执行的是非增、删、改操作,返回-1
        /// </summary>
        /// <param name="cmdText">要执行的T-SQL语句</param>
        /// <param name="parameters">参数列表</param>
        /// <exception cref="链接数据库异常"></exception>
        /// <returns>受影响的行数</returns>
        public static int ExecuteNonQuery(string cmdText, params SqlParameter[] parameters)
        {
            return ExecuteNonQuery(cmdText, CommandType.Text, parameters);
        }
        #endregion

        #region ExecuteNonQuery +static int ExecuteNonQuery(string cmdText, CommandType type, params SqlParameter[] parameters)
        /// <summary>
        /// 执行一个非查询的T-SQL语句,返回受影响行数,如果执行的是非增、删、改操作,返回-1
        /// </summary>
        /// <param name="cmdText">要执行的T-SQL语句</param>
        /// <param name="type">命令类型</param>
        /// <param name="parameters">参数列表</param>
        /// <exception cref="链接数据库异常"></exception>
        /// <returns>受影响的行数</returns>
        public static int ExecuteNonQuery(string cmdText, CommandType type, params SqlParameter[] parameters)
        {
            using (SqlConnection conn = new SqlConnection(ConnectionStringCustomers))
            {
                using (SqlCommand cmd = new SqlCommand(cmdText, conn))
                {
                    if (parameters != null)
                    {
                        cmd.Parameters.Clear();
                        cmd.Parameters.AddRange(parameters);
                    }
                    cmd.CommandType = type;
                    try
                    {
                        conn.Open();
                        int res = cmd.ExecuteNonQuery();
                        cmd.Parameters.Clear();
                        return res;
                    }
                    catch (System.Data.SqlClient.SqlException e)
                    {
                        conn.Close();
                        throw e;
                    }
                }
            }
        }
        #endregion

        #region ExecuteReader +static SqlDataReader ExecuteReader(string cmdText, params SqlParameter[] parameters)
        /// <summary>
        /// 执行一个查询的T-SQL语句, 返回一个SqlDataReader对象, 如果出现SQL语句执行错误, 将会关闭连接通道抛出异常
        ///  ( 注意:调用该方法后,一定要对SqlDataReader进行Close )
        /// </summary>
        /// <param name="cmdText">要执行的T-SQL语句</param>
        /// <param name="parameters">参数列表</param>
        /// <exception cref="链接数据库异常"></exception>
        /// <returns>SqlDataReader对象</returns>
        public static SqlDataReader ExecuteReader(string cmdText, params SqlParameter[] parameters)
        {
            return ExecuteReader(cmdText, CommandType.Text, parameters);
        }
        #endregion

        #region ExecuteReader +static SqlDataReader ExecuteReader(string cmdText, CommandType type, params SqlParameter[] parameters)
        /// <summary>
        /// 执行一个查询的T-SQL语句, 返回一个SqlDataReader对象, 如果出现SQL语句执行错误, 将会关闭连接通道抛出异常
        ///  ( 注意:调用该方法后,一定要对SqlDataReader进行Close )
        /// </summary>
        /// <param name="cmdText">要执行的T-SQL语句</param>
        /// <param name="type">命令类型</param>
        /// <param name="parameters">参数列表</param>
        /// <exception cref="链接数据库异常"></exception>
        /// <returns>SqlDataReader对象</returns>
        public static SqlDataReader ExecuteReader(string cmdText, CommandType type, params SqlParameter[] parameters)
        {
            SqlConnection conn = new SqlConnection(ConnectionStringCustomers);
            using (SqlCommand cmd = new SqlCommand(cmdText, conn))
            {
                if (parameters != null)
                {
                    cmd.Parameters.Clear();
                    cmd.Parameters.AddRange(parameters);
                }
                cmd.CommandType = type;
                conn.Open();
                try
                {
                    SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
                    cmd.Parameters.Clear();
                    return reader;
                }
                catch (System.Data.SqlClient.SqlException ex)
                {
                    //出现异常关闭连接并且释放
                    conn.Close();
                    throw ex;
                }
            }
        }
        #endregion

        #region 将一个SqlDataReader对象转换成一个实体类对象 +static T MapEntity<T>(SqlDataReader reader) where T : class,new()
        /// <summary>
        /// 将一个SqlDataReader对象转换成一个实体类对象
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="reader">当前指向的reader</param>
        /// <returns>实体对象</returns>
        public static T MapEntity<T>(SqlDataReader reader)
        {
            try
            {
                Type type = typeof(T);
                var props = type.GetProperties();

                object entity = Activator.CreateInstance(type);//创建返回的单个对象
                foreach (var prop in props)
                {
                    if (prop.CanWrite)
                    {
                        try
                        {
                            var index = reader.GetOrdinal(prop.Name);
                            var data = reader.GetValue(index);
                            if (data != DBNull.Value)
                            {
                                prop.SetValue(entity, Convert.ChangeType(data, prop.PropertyType), null);
                            }
                        }
                        catch (IndexOutOfRangeException)
                        {
                            continue;
                        }
                    }
                }
                return (T)entity;
            }
            catch(Exception ex)
            {
                return default(T);
            }
        }
        #endregion

        #endregion

    }
}

2、我们在 LambdaAndGeneric.IDAL类库下

新建: BaseIDAL.cs类

代码如下:

using System.Collections.Generic;

namespace LambdaAndGeneric.IDAL
{
    /// <summary>
    /// 说明: BaseIDAL 的封装
    /// 时间:2018年8月15日
    /// 作用:用于被继承,减少代码
    /// 作者:null
    /// </summary>
    /// <typeparam name="T">约束对象</typeparam>
    public interface BaseIDAL<T> where T : new()
    {

        /// <summary>
        /// 执行一个插入操作
        /// </summary>
        /// <typeparam name="W"></typeparam>
        /// <param name="Entity"></param>
        /// <returns></returns>
        bool ADD(T Entity);

        /// <summary>
        /// 根据ID删除一条数据
        /// </summary>
        /// <param name="ID"></param>
        /// <returns></returns>
        bool Del(int ID);

        /// <summary>
        /// 根据Model更新一条数据
        /// </summary>
        /// <param name="Entity"></param>
        /// <returns></returns>
        bool Update(T Entity);

        /// <summary>
        /// 获得单个实体
        /// </summary>
        /// <param name="ID"></param>
        /// <returns></returns>
        T GetEntity(int ID);

        /// <summary>
        /// 根据条件查询,并返回一个IEnumerable<T>类型的集合
        ///  (注意传入的 T 必须约束为 where T : class, new())
        /// </summary>
        /// <param name="where"> 参数省略【where】关键字</param>
        /// <returns></returns>
        IEnumerable<T> GetEntityList(string where);

        /// <summary>
        ///  执行传入的Sql语句,并返回一个IEnumerable<T>类型的集合
        ///  (注意传入的 T 必须约束为 where T : class, new())
        /// </summary>
        /// <param name="sql">执行的SQL语句</param>
        /// <returns></returns>
        IEnumerable<W> GetEntityListSQl<W>(string sql);
    }
}

3、我们在LambdaAndGeneric.DAL类库下

新建: BaseDAL.cs类用于继承IDAL

代码如下:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Reflection;
using System.Text;
using LambdaAndGeneric.IDAL;
using LamdbaAndGeneric.HelperDAL;

namespace LambdaAndGeneric.DAL
{
    /// <summary>
    /// 说明: BaseDAL 的封装
    /// 时间:2018年8月15日
    /// 作用:用于被继承,减少代码
    /// 作者:null
    /// </summary>
    /// <typeparam name="T">约束对象</typeparam>
    public class BaseDAL<T> : BaseIDAL<T> where T : new()
    {

        #region 根据Model更新一条数据

        /// <summary>
        /// 根据Model更新一条数据
        /// </summary>
        /// <param name="Entity"></param>
        /// <returns></returns>
        public bool Update(T Entity)
        {
            Type type = typeof(T);
            object oT = Activator.CreateInstance(type);

            var oEntity = Entity.GetType().GetProperties();//

            StringBuilder builder = new StringBuilder(256);
            StringBuilder builderWhere = new StringBuilder(256);

            foreach (var item in oEntity)
            {
                //字段和值得拼接
                if (!item.Name.Equals("ID", StringComparison.InvariantCultureIgnoreCase) && !item.Name.Equals("FID", StringComparison.InvariantCultureIgnoreCase))
                {
                    builder.Append(item.Name + "=" + item.GetValue(oT));
                }
                //获取ID条件
                if (item.Name.Equals("ID", StringComparison.InvariantCultureIgnoreCase) || item.Name.Equals("FID", StringComparison.InvariantCultureIgnoreCase))
                {
                    builderWhere.Clear();
                    builderWhere.Append(item.Name + "=" + item.GetValue(oT));
                }
            }

            string execSql = $" update {type.Name} {builder.ToString()} where {builderWhere.ToString()}";

            return SenctionHelper.ExecuteNonQuery(execSql) > 0; //SenctionHelper<T>.ExecuteNonQuery(execSql) > 0;
        }

        #endregion

        #region 根据ID删除一条数据

        /// <summary>
        /// 根据ID删除一条数据
        /// </summary>
        /// <param name="ID"></param>
        /// <returns></returns>
        public bool Del(int ID)
        {
            Type type = typeof(T);

            string execSql = $" delete from {type.Name} where ID={ID} ";
            return SenctionHelper.ExecuteNonQuery(execSql) > 0;
        }

        #endregion

        #region 插入一条数据
        /// <summary>
        /// 执行一个插入操作
        /// </summary>
        /// <typeparam name="W"></typeparam>
        /// <param name="Entity"></param>
        /// <returns></returns>
        public bool ADD(T Entity)
        {
            Type type = typeof(T);
            object oT = Activator.CreateInstance(type);
            PropertyInfo[] propertys = Entity.GetType().GetProperties();
            StringBuilder builder = new StringBuilder();

            //获取字段
            var section = string.Join(",", type.GetProperties().Where(w => !w.Name.Equals("ID", StringComparison.CurrentCultureIgnoreCase) && !w.Name.Equals("FID", StringComparison.CurrentCultureIgnoreCase)).Select(s => s.Name));

            //获取值
            var value = "‘" + string.Join("‘,‘", propertys.Where(w => !w.Name.Equals("ID", StringComparison.CurrentCultureIgnoreCase) && !w.Name.Equals("FID", StringComparison.CurrentCultureIgnoreCase)).Select(p => p.GetValue(Entity))) + "‘";

            string execSql = $" insert into {type.Name}({section}) values({value}) ";

            return SenctionHelper.ExecuteNonQuery(execSql) > 0;
        }

        #endregion

        #region 获得单个实体
        /// <summary>
        /// 获得单个实体
        /// </summary>
        /// <param name="ID"></param>
        /// <returns></returns>
        public T GetEntity(int ID)
        {
            Type type = typeof(T);
            string sql = $" SELECT {SenctionHelper.GetModelSenction<T>()} from {type.Name} ";

            try
            {
                using (SqlDataReader reader = SenctionHelper.ExecuteReader(sql))
                {
                    if (reader.HasRows)
                    {
                        reader.Read();
                        return SenctionHelper.MapEntity<T>(reader);
                    }
                    else
                    {
                        return default(T);
                    }

                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return default(T);
            }

        }
        #endregion

        #region  根据传入的条件执行Sql语句,并返回一个IEnumerable<T>类型的集合

        /// <summary>
        ///  根据传入的SQL语句执行查询,并返回一个IEnumable<T>类型的集合
        ///  注意 W 必须约束为 where W : class, new())
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public IEnumerable<W> GetEntityListSQl<W>(string sql)
        {
            using (SqlDataReader reader = SenctionHelper.ExecuteReader(sql))
            {
                if (reader.HasRows)
                {
                    while (reader.Read())
                    {
                        yield return SenctionHelper.MapEntity<W>(reader);
                    }
                }
            }
        }

        #endregion

        #region  根据传入的条件执行Sql语句,并返回一个IEnumerable<T>类型的集合

        /// <summary>
        /// 根据传入的条件执行查询,并返回一个IEnumerable<T>类型的集合
        /// (注意传入的 T 必须约束为 where T : class, new())
        /// </summary>
        /// <typeparam name="T">类型:【 约束为 where T : class, new() 】</typeparam>
        /// <param name="where">查询的条件,请省略 Where 关键字</param>
        /// <returns></returns>
        public IEnumerable<T> GetEntityList(string where)
        {
            Type type = typeof(T);
            //遍历获得字段
            //string columnString = string.Join(",", type.GetProperties().Select(p => string.Format("[{0}]", p.Name)));
            string sql = string.Format("SELECT {0} FROM [{1}] WHere {2} ",
               SenctionHelper.GetModelSenction<T>(),
                type.Name,
                where);
            using (SqlDataReader reader = SenctionHelper.ExecuteReader(sql))
            {
                if (reader.HasRows)
                {
                    while (reader.Read())
                    {
                        yield return SenctionHelper.MapEntity<T>(reader);
                    }
                }
            }
        }

        #endregion
    }
}

4、我们在LambdaAndGeneric.IBLL类库下

新建: BaseIBLL.cs类

代码如下:

using System.Collections.Generic;

namespace LambdaAndGeneric.IBLL
{
    /// <summary>
    /// 说明: BaseIBLL 的封装
    /// 时间:2018年8月15日11:11:31
    /// 作用:用于被继承,减少代码
    /// 作者:null
    /// </summary>
    /// <typeparam name="T">约束对象</typeparam>
    public interface BaseIBLL<T> where T: new()
    {
        /// <summary>
        /// 执行一个插入操作
        /// </summary>
        /// <typeparam name="W"></typeparam>
        /// <param name="Entity"></param>
        /// <returns></returns>
        bool ADD(T Entity);
        /// <summary>
        /// 根据ID删除一条数据
        /// </summary>
        /// <param name="ID"></param>
        /// <returns></returns>
        bool Del(int ID);
        /// <summary>
        /// 根据Model更新一条数据
        /// </summary>
        /// <param name="Entity"></param>
        /// <returns></returns>
        bool Update(T Entity);
        /// <summary>
        /// 获得单个实体
        /// </summary>
        /// <param name="ID"></param>
        /// <returns></returns>
        T GetEntity(int ID);

        /// <summary>
        /// 根据条件查询,并返回一个IEnumerable<T>类型的集合
        ///  (注意传入的 T 必须约束为 where T : class, new())
        /// </summary>
        /// <param name="where"> 参数省略【where】关键字</param>
        /// <returns></returns>
        IEnumerable<T> GetEntityList(string where); 

        /// <summary>
        ///  执行传入的Sql语句,并返回一个IEnumerable<T>类型的集合
        ///  (注意传入的 T 必须约束为 where T : class, new())
        /// </summary>
        /// <param name="sql">执行的SQL语句</param>
        /// <returns></returns>
        IEnumerable<W> GetEntityListSQl<W>(string sql);
    }
}

5、我们在LambdaAndGeneric.BLL类库下

新建: BaseBLL.cs类 继承 BaseIBLL.cs

代码如下

using System.Collections.Generic;
using LambdaAndGeneric.DAL;
using LambdaAndGeneric.IBLL;
using LambdaAndGeneric.IDAL;

namespace LambdaAndGeneric.BLL
{
    /// <summary>
    /// 说明: BaseBLL 的封装
    /// 时间:2018年8月15日11:11:31
    /// 作用:用于被继承,减少代码
    /// 作者:null
    /// </summary>
    /// <typeparam name="T">约束对象</typeparam>
    public class BaseBLL<T> : BaseIBLL<T> where T : new()
    {
        private BaseIDAL<T> dao = new BaseDAL<T>();

        /// <summary>
        /// 增加一条数据
        /// </summary>
        /// <param name="Entity">传入的增加的实体Model</param>
        /// <returns></returns>
        public bool ADD(T Entity)
        {
            return dao.ADD(Entity);
        }

        /// <summary>
        /// 根据ID删除一条数据
        /// </summary>
        /// <param name="ID">删除ID</param>
        /// <returns></returns>
        public bool Del(int ID)
        {
            return dao.Del(ID);
        }

        /// <summary>
        ///根据实体更新一条数据
        /// </summary>
        /// <param name="Entity">传入更新的实体Model</param>
        /// <returns></returns>
        public bool Update(T Entity)
        {
            return dao.Update(Entity);
        }

        /// <summary>
        /// 获得单个实体
        /// </summary>
        /// <param name="ID">查询ID</param>
        /// <returns></returns>
        public T GetEntity(int ID)
        {
            return dao.GetEntity(ID);
        }

        /// <summary>
        ///  根据传入的条件执行查询,并返回一个IEnumerable<T>类型的集合
        ///  (注意传入的 T 必须约束为 where T : class, new())
        /// </summary>
        /// <param name="where">查询条件,请省略 where 关键字</param>
        /// <returns></returns>
        public IEnumerable<T> GetEntityList(string where)
        {
            return dao.GetEntityList(where);
        }

        /// <summary>
        /// 根据传入的SQL语句执行查询,并返回一个IEnumable<T>类型的集合
        /// 注意 T 必须约束为 where W : class, new())
        /// </summary>
        /// <typeparam name="W">返回的单个Model实体</typeparam>
        /// <param name="sql">执行的SQL语句</param>
        /// <returns></returns>
        public IEnumerable<W> GetEntityListSQl<W>(string sql)
        {
            return dao.GetEntityListSQl<W>(sql);
        }
    }
}

6、我们在LambdaAndGeneric.Model类库下

新建: 一个Company 的实体

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LambdaAndGeneric.Model
{
    public class Company
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public DateTime CreateTime { get; set; }
        public int CreatorId { get; set; }
        public int LastModifierId { get; set; }
        public DateTime LastModifyTime { get; set; }
    }
}

数据库新建张表

USE [XXX]
GO

/****** Object:  Table [dbo].[Company]    Script Date: 2018-08-16 12:00:11 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Company](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](50) NULL,
    [CreateTime] [datetime] NULL,
    [CreatorId] [int] NULL,
    [LastModifierId] [int] NULL,
    [LastModifyTime] [datetime] NULL,
 CONSTRAINT [PK_Company] PRIMARY KEY CLUSTERED
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

6、最后我们在控制台测试一下

using LambdaAndGeneric.BLL;
using LambdaAndGeneric.DAL;
using LambdaAndGeneric.IBLL;
using LambdaAndGeneric.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            {
                CompanyIBLL<Company> company = new CompanyBLL();
                var xx = company.GetEntity(1);

                var result = company.ADD(new Company() { CreateTime = System.DateTime.Now, CreatorId = 2, ID = 2, LastModifierId = 2, LastModifyTime = System.DateTime.Now, Name = "xxx" });
                Console.WriteLine(result);

                {
                    Console.WriteLine("*****************************GetEntityListSQl***********************************");
                    var list = company.GetEntityListSQl<Company>("  SELECT  * from company ");
                    foreach (var item in list)
                    {
                        Console.WriteLine(item.ID + "***" + item.LastModifierId + "**" + item.LastModifyTime + "***" + item.Name);
                    }
                }

                {
                    Console.WriteLine("*****************************GetEntityList***********************************");
                    var listbll = company.GetEntityList("id>0");
                    foreach (var item in listbll)
                    {
                        Console.WriteLine(item.ID + "***" + item.LastModifierId + "**" + item.LastModifyTime + "***" + item.Name);
                    }
                }
                Console.ReadKey();
            }
        }
    }
}

注意这里执行 GetEntityListSQl<T> 方法时,可以进行多表连接查询,但是要传入对应查询字段的实体,。这个还得自己封装Model。

原文地址:https://www.cnblogs.com/NorthMeditation/p/9486443.html

时间: 2024-11-05 16:00:53

asp.net泛型结合反射的简单Base封装的相关文章

实施 ORM 的两项要旨:泛型和反射

鄙人认为,实施 ORM 的两项要旨乃泛型和反射.下面开始看看怎么为 DAO 层添砖加瓦. 首先,在 DBAccess 基础上扩展 DBAccessORM 接口,形成基于 ORM 的数据调用. /** * 数据访问对象 * * @author Frank Cheung * */ public interface DBAccessORM extends DBAccess { /** * 查询单笔记录,返回实体 * * @param sql * 原生 SQL 语句 * @param clazz * P

Java高质量代码之 — 泛型与反射

在Java5后推出了泛型,使我们在编译期间操作集合或类时更加的安全,更方便代码的阅读,而让身为编译性语言的Java提供动态性的反射技术,更是在框架开发中大行其道,从而让Java活起来,下面看一下在使用泛型和反射需要注意和了解的事情? 1.Java的泛型是类型擦除的????? Java中的泛型是在编译期间有效的,在运行期间将会被删除,也就是所有泛型参数类型在编译后都会被清除掉.请看以下例子? Java代码??? publicstaticvoid?test(List??testParameter)?

应用Java泛型和反射导出CSV文件

项目中有需求要把数据导出为CSV文件,因为不同的类有不同的属性,为了代码简单,应用Java的泛型和反射,写了一个函数,完成导出功能. public <T> void saveFile(List<T> list, String outFile) throws IOException { if (list == null || list.isEmpty()) { return; } if (StringUtils.isEmpty(outFile)) { throw new Illega

支持泛型AVL Tree的简单实现,并和STL map比较了插入,删除,查找的性能

1.问题描述: 1)AVL tree是一种自平衡树.它通过左右子树的高度差来控制树的平衡,当高度差是不大于1的时候,认为树是平衡的.树的平衡保证了树在极端情况下 (输入序列不够随机)的性能.很显然当左右子树高度平衡,保证了任何插入,删除,查找操作平均性能呢个,当不平衡时(有的子树很高),当 要操作的元素在这个子树时,性能会很差: 2)AVL tree 和Red black tree 都是一种平衡树,它的操作的时间复杂度是:O(lgN) ,N是树的节点的数目: 3)本文实现了AVL Tree, 并

用泛型和反射实现函数通用

使用泛型和反射机制事项函数的通用,写下来,欢迎吐槽 代码示例使用vb. net Imports System.Reflection Module Module1 Sub Main() Dim lst1 As List(Of Person) = New List(Of Person)() Dim lst2 As List(Of Person) = New List(Of Person)() Dim lstT As List(Of Person) = New List(Of Person)() Fo

C++利用反射和简单工厂模式实现业务模块解耦

1. 业务说明 为了便于说明,举一个简单的例子.假设现在有一个项目需要建立一个和银行交互的平台,目前只接入工商银行,后续接入其他银行,每个银行的业务都有差异,报文格式可能也不一致. 这里只列举几个简要的流程,仅包括拼报文,发送报文,接收报文,解析报文,其余整体架构以及后续处理等内容省略. 2. 初步设计 创建一个银行交互类 BankOpt,包括四个函数: int setMsg(); //拼报文 int sendMsg(); //发送报文 int getMsg(); //接收报文 int pars

通过java反射实现简单的关于MongoDB的对象关系映射(ORM).

通过阅读MongoDB  3.2.1的官方文档中关于java 编程发现最新的文档并没有实现对对象到Document的映射,所以自己有了利用反射实现简单的关系映射. 1.定义抽象类:AbstractMongoSession import java.util.List; import org.bson.Document; import org.bson.conversions.Bson; import com.mongodb.client.MongoCollection; import com.mo

Asp.Net 控件radio 的简单使用

js: <script type="text/javascript"> function ok() { document.getElementById("txtPassword").disabled = false; } function no() { document.getElementById("txtPassword").disabled = true; } </script> 添加radio控件: <lab

ASP.NET中登录功能的简单逻辑设计

 ASP.NET中登录功能的简单逻辑设计                               概述                               逻辑设计                               1.接收参数                               2.判断参数合法性                               3.访问数据库                               4.保存Session