zoukankan      html  css  js  c++  java
  • Core1.1环境下,自己实现的一个简单的CRUD框架(反射实现)

    我实现了一个简单的EF框架,主要用于操纵数据库。实现了对数据库的基本操纵--CRUD

    这是项目结构 这是一个 core 下的 DLL

    写了一个数据库工厂,用于执行sql语句。调用sql语句工厂

    写了一个sql语句工厂,用于生成sql语句。调用类型工厂

    写了一个类型工厂,用于获取所需的类型,识别特性等。

    appsettings.json是配置文件 

    最后一个是使用说明

    我实现过程的首先从底层开始。

    首先写的是类型工厂

    结构

    BaseTypeHelper.cs 是基础的类型帮助类

    TypeHelperFactory.cs是一个工厂,调用BaseTypeHelper.cs,是现自己的功能,同时为sql语句工厂提供服务。

    首先介绍一下BaseTypeHelper.cs类。这是代码。为TypeHelperFactory提供了必要的服务

      1  public static class BaseTypeHelper
      2     {
      3         #region 获取单个成员
      4         private static MemberInfo GetOneMember(Type t, string MemberName)
      5         {
      6             return GetAllMembers(t).FirstOrDefault(m => m.Name == MemberName);
      7         }
      8 
      9         #endregion
     10 
     11         #region 获取所有成员
     12         public  static MemberInfo[] GetAllMembers(Type t)
     13         {
     14             return t.GetMembers();
     15         }
     16 
     17         #endregion
     18 
     19         #region 获取成员的属性
     20 
     21         /// <summary>
     22         /// 获取成员的属性
     23         /// </summary>
     24         /// <param name="obj">目标类</param>
     25         /// <param name="MemberName">成员名称</param>
     26         /// <returns></returns>
     27         private static PropertyInfo GetProperty(object obj, string MemberName)
     28         {
     29             var type = obj.GetType(); 
     30             var member = GetOneMember(type, MemberName);
     31             return type.GetProperty(member.Name);
     32 
     33         }
     34         #endregion
     35 
     36         #region 执行法并返回结果    
     37         /// <summary>
     38         /// 获取方法的返回值
     39         /// </summary>
     40         /// <param name="MethodName">方法的名称</param>
     41         /// <param name="instance">实例</param>
     42         /// <param name="param">参数列表,如果没有参数则置为null</param>
     43         /// <returns></returns>
     44         public static object GetMethodValue(string MethodName, object instance, params object[] param)
     45         {
     46             Type t = instance.GetType();
     47             try
     48             {
     49                 MethodInfo info = t.GetMethod(MethodName);
     50                 return info.Invoke(instance, param);
     51             }
     52             catch (Exception e)
     53             {
     54                 Console.WriteLine("方法没有找到," + e);
     55                 throw;
     56             }
     57 
     58         }
     59         #endregion
     60 
     61         #region 获取声明成员的类型
     62 
     63         /// <summary>
     64         /// 获取声明成员的类型
     65         /// 说明:返回若为空则 没有找到
     66         /// 若不为空,则查找正常
     67         /// </summary>
     68         /// <param name="MemberName">成员的名称</param>
     69         /// <param name="t">所在类的类型</param>
     70         /// <returns></returns>
     71         public static string GetPropertyType(string MemberName, Type t)
     72         {
     73             MemberInfo member = GetOneMember(t, MemberName);
     74             if (member != null)
     75             {
     76                 PropertyInfo property = t.GetProperty(member.Name);
     77                 return property.PropertyType.Name;
     78             }
     79             return null;
     80 
     81         }
     82         #endregion
     83 
     84         #region 获取单个成员是否含有某个属性
     85 
     86 
     87         /// <summary>
     88         /// 获取单个成员是否含有某个特性
     89         /// </summary>
     90         /// <param name="MemberName">成员的名称</param>
     91         /// <param name="t">所在类的类型</param>
     92         /// <param name="attribute">要获取的特性</param>
     93         /// <returns></returns>
     94         public static bool CustomAttributeExist(string MemberName, Type t, Attribute attribute)
     95         {
     96 
     97             var Member = GetOneMember(t, MemberName);
     98             var My_customAttribute = Member.CustomAttributes.FirstOrDefault(
     99                               a => a.AttributeType == attribute.GetType());
    100             return My_customAttribute != null;
    101         }
    102         #endregion
    103 
    104         #region 通过SetValue给成员设值
    105   
    106         /// <summary>
    107         /// 给成员设值
    108         /// </summary>
    109         /// <param name="obj">目标类</param>
    110         /// <param name="MemberName">类内属性名称</param>
    111         /// <param name="value">设置的值</param>
    112         public static void SetValue(object obj, string MemberName, object value)
    113         {
    114             var Property = GetProperty(obj, MemberName);
    115             Property.SetValue(obj, value);
    116         }
    117         #endregion
    118 
    119         #region 通过GetValue给成员取值
    120     
    121         /// <summary>
    122         /// 取成员的值
    123         /// </summary>
    124         /// <param name="obj">目标类</param>
    125         /// <param name="MemberName">成员的名称</param>
    126         /// <returns></returns>
    127         public static object GetValue(object obj, string MemberName)
    128         {
    129             var Property = GetProperty(obj, MemberName);
    130             return Property.GetValue(obj);
    131         }
    132         #endregion
    133         
    134         
    135     }
    BaseTypeHelper.cs

    这是TypeHelperFactory.cs 这是一个工厂,利用BaseTypeHelper.cs 提供的服务的基础之上为上层,提供这么几个功能,获取所有的属性列表,获取属性和值的字典集,获取主键(实现了特性[key]的识别,以及默认的ID.toLower()),获取表名(这里获取表名的时候,只是简单的实现了获取类的名称,并没有实现获取特性[Table(Name="...")]这个功能,会在以后更新上去的),获取主键的名称,获取主键的值,获取声明主键的类型,给属性设值。

      1     public static class TypeHelperFactory
      2     {
      3         #region GetAllPropertyList
      4 
      5         public static List<string> GetAllPropertyList(Type type)
      6         {
      7             var Propertys = BaseTypeHelper
      8                           .GetAllMembers(type)
      9                           .ToList()
     10                           .FindAll(member => member.MemberType == MemberTypes.Property);
     11             var PropertyList = new List<string>();
     12             foreach (var item in Propertys)
     13             {
     14                 PropertyList.Add(item.Name);
     15             }
     16             return PropertyList;
     17         }
     18 
     19         #endregion
     20 
     21         #region GetAllPropertyNameAndValueDictionary
     22         //添加到字典中的时候已经去除掉空的值
     23         public static Dictionary<string, object> GetAllPropertyNameAndValueDictionary(object obj)
     24         {
     25             Type type = obj.GetType();
     26             var PropertyList = GetAllPropertyList(type);
     27             var PropertyValueList = new Dictionary<string, object>();
     28             foreach (var Property in PropertyList)
     29             {
     30                 var value = BaseTypeHelper.GetValue(obj, Property);
     31                 if (value == null) continue;
     32                 PropertyValueList.Add(Property, value);
     33             }
     34             return PropertyValueList;
     35         }
     36 
     37         #endregion
     38 
     39         #region GetTableName
     40         /// <summary>
     41         ///简单获取类的名称
     42         /// 未查找特性[table(Name="")]的标注
     43         /// 2017-5-9 18:00 
     44         /// Author :曲
     45         /// </summary>
     46         /// <param name="type"></param>
     47         /// <returns></returns>
     48         public static string GetTableName(Type type)
     49         {
     50             return type.Name;
     51         }
     52 
     53         #endregion
     54 
     55         #region GetPrimaryKey
     56 
     57         public static string GetPrimaryKey(Type type)
     58         {
     59             //1.查找特性标注为key的
     60             //2.如果不存在 查找 类型为int和名称为ID/Id/id 的
     61             var memberNameList = GetAllPropertyList(type);
     62             var attrribute = new KeyAttribute();
     63 
     64             foreach (var item in memberNameList)
     65             {
     66                 if (BaseTypeHelper.CustomAttributeExist(item, type, attrribute))
     67                 {
     68                     return item;
     69                 }
     70             }
     71             return memberNameList.FirstOrDefault(
     72                                                    key => key.ToLower() == "id"
     73                                                    && BaseTypeHelper
     74                                                       .GetPropertyType(key, type)
     75                                                       .Contains("Int")
     76                                                    );
     77 
     78         }
     79 
     80         #endregion
     81 
     82         #region GetPrimaryKeyValue
     83 
     84         public static object GetPrimaryKeyValue(object obj, string PrimaryKeyName)
     85         {
     86             return BaseTypeHelper.GetValue(obj, PrimaryKeyName);
     87         }
     88 
     89         #endregion
     90 
     91         #region GetPrimaryKeyType
     92 
     93         public static string GetPrimaryKeyType(Type type, string PrimaryKey)
     94         {
     95             return BaseTypeHelper.GetPropertyType(PrimaryKey, type);
     96         }
     97 
     98 
     99         #endregion
    100 
    101         #region SetPropertyValue
    102 
    103         public static void SetPropertyValue(object obj, string MemberName, object value)
    104         {
    105             BaseTypeHelper.SetValue(obj, MemberName, value);
    106         }
    107 
    108         #endregion
    109     }
    TypeHelperFactory.cs

    接下来写的是sql语句构造工厂,这是工厂结构。

    两个文件夹,一个实现接口文件夹,一个接口文件夹。两个类,一个枚举类,一个对外提供服务的类,也就是外界只能通过这一个类,获取我这一层对外提供的服务。

    首先介绍一下接口文件夹 :里边定义了接口的类型,以及方法 

    里边有五个接口,分别是ICreate、IDelete、IRead、IUpdate、ISqlStatementBuilder。

    对这五个接口进行说明一下,ISqlStatementBuilder是总的接口,即对外提供服务的接口,分别继承了CURD这四个接口。

        public interface ISqlStatementBuilder : ICreate, IRead, IUpdate, IDelete
        {
    
        }
    ISqlStatementBuilder.cs
    1     public interface ICreate
    2     {
    3         string CreateSqlString(object obj);
    4     }
    ICreate.cs
    1     public interface IDelete
    2     {
    3         string DeleteSqlString(object obj);
    4        
    5     }
    IDelete.cs
    1     public interface IRead
    2     {
    3         string ReadSqlString(object obj);
    4     }
    IRead.cs
    1     public interface IUpdate
    2     {
    3         string UpdateSqlString(object obj);
    4     }
    IUpdate.cs

    接下来是:实现接口文件夹,这个文件夹包含了三类数据库的对应的sql不同的sql语句。MySql,Oracle,SqlServer,这里我只实现了sqlserver对应的数据库的sql语句。

        public class SqlServerSqlStatement :ISqlStatementBuilder
        {
    
            #region  获取Insertsql语句 实现ICreate接口
    
            public string CreateSqlString(object obj)
            {
                var type = obj.GetType();
                var TableName = TypeHelperFactory.GetTableName(type);
                var PrimaryKeyName = TypeHelperFactory.GetPrimaryKey(type);
                var PropertyNameAndValueDictionary = TypeHelperFactory.GetAllPropertyNameAndValueDictionary(obj);
                PropertyNameAndValueDictionary.Remove(PrimaryKeyName);
                //这里进行了修改 2017-5-17 17:10 
                //这是原来的代码
                //var PropertyNameList = new List<string>();
                //var PropertyValueList = new List<object>();           
                //foreach (var item in PropertyNameAndValueDictionary)
                //{
                //    PropertyNameList.Add(item.Key);
                //    PropertyValueList.Add(item.Value);
                //}
                //这是新的代码 测试已通过 以后考虑用元组实现 2017-5-17 17:15
                var PropertyNameList = from item in PropertyNameAndValueDictionary
                                       select item.Key;
                var PropertyValueList = from item in PropertyNameAndValueDictionary
                                        select item.Value;
                string sql1 = string.Join(",", PropertyNameList);
                string sql2 = "'";
                sql2 += string.Join("','", PropertyValueList);
                sql2 += "'";
                var SqlStatement = new StringBuilder();
                SqlStatement.AppendFormat($"insert into {TableName} ({sql1}) values ({sql2})");
                return SqlStatement.ToString();
    
            }
    
            #endregion
             
            #region 获取Readsql语句 实现IRead接口
    
            public string ReadSqlString(object obj)
            {
                var type = obj.GetType();
                var PropertyList = TypeHelperFactory.GetAllPropertyList(type);
                var TableName = TypeHelperFactory.GetTableName(type);
                string SelectString = string.Join(",", PropertyList);
                StringBuilder SqlStatement = new StringBuilder();
                SqlStatement.AppendFormat($"select {SelectString} from {TableName}");
                return SqlStatement.ToString();
            }
    
            #endregion
    
            #region 获取Updatesql语句 实现IUpdate接口
            public string UpdateSqlString(object obj)
            {
                var type = obj.GetType();
                var TableName = TypeHelperFactory.GetTableName(type);
                var PrimaryKeyName = TypeHelperFactory.GetPrimaryKey(type);
                if (PrimaryKeyName == null)
                {
                    throw new Exception("不存在主键");
                }
                var PrimaryKeyValue = TypeHelperFactory.GetPrimaryKeyValue(obj, PrimaryKeyName);
                var PropertyNameAndValueDictionary = TypeHelperFactory.GetAllPropertyNameAndValueDictionary(obj);
                PropertyNameAndValueDictionary.Remove(PrimaryKeyName);
                //这里进行了修改 2017-5-17 17:00
                //这是原来的代码
                //var NameAndValueList = new List<string>();
                //foreach (var item in PropertyNameAndValueDictionary)
                //{
                //    NameAndValueList.Add($"{item.Key}='{item.Value}'");
                //}
    
                //这是新的代码 2017-5-17 17:00 测试已通过
                var NameAndValueList = from item in PropertyNameAndValueDictionary
                                       select $"{item.Key}='{item.Value}'";
                string sql = string.Join(",", NameAndValueList);
                StringBuilder sqlStatement = new StringBuilder();
                sqlStatement.AppendFormat(
                                          $"update {TableName} set {sql} " +
                                          $"where {PrimaryKeyName}='{PrimaryKeyValue}'"
                                         );
                return sqlStatement.ToString();
            }
    
    
    
            #endregion
    
            #region 获取Deletesql语句 实现IDelete接口
            public string DeleteSqlString(object obj)
            {
                var type = obj.GetType();
                var TableName = TypeHelperFactory.GetTableName(type);
                var PrimaryKey = TypeHelperFactory.GetPrimaryKey(type);
                if (PrimaryKey == null)
                {
                    throw new Exception("不存在主键");
                }
                var PrimaryKeyValue = TypeHelperFactory.GetPrimaryKeyValue(obj, PrimaryKey);
                StringBuilder SqlStatement = new StringBuilder();
                SqlStatement.AppendFormat($"delete from {TableName} where {PrimaryKey}='{PrimaryKeyValue}'");
                return SqlStatement.ToString();
            }
    
    
            #endregion
        }
    SqlServerSqlStatement.cs

    这个类实现了ISqlStatementBuilder这个接口里边定义的方法。其余的两个类只是继承了接口,并没有实现接口定义的具体方法。

    接下来这一层的重点来了!

    首先这是一个数据库的枚举类

       /// <summary>
        /// 这是一个枚举类型 用于枚举数据库的类型
        /// </summary>
        public  enum  DataBaseType
        {
            SqlServer = 1,
            MySql = 2,
            Oracle = 3
        }
    DataBaseType.cs

    接下来这是对外提供服务的一个类,我用反射获取枚举过来的数据库的类型字符串,然后通过反射生成对应的实例。(这个东西的详细用法,我的这篇博客里有介绍http://www.cnblogs.com/qulianqing/p/6842829.html

     1     public static class SqlBuilderFactory
     2     {
     3         public static ISqlStatementBuilder GetInstance(DataBaseType DbType)
     4         {         
     5             string DataBaseTypeName = Enum.Parse(DbType.GetType(), DbType.ToString()).ToString();
     6             var NamespaceName = "MyEntityFrameWork.SqlBuilderFactorys.Implement";
     7             string InstanceClassName = DataBaseTypeName + "SqlStatement";
     8             return (ISqlStatementBuilder)Assembly.Load(new AssemblyName("MyEntityFrameWork"))
     9                                               .CreateInstance(NamespaceName+"."+InstanceClassName);
    10         }
    11         
    12     }

    对于外界调用只用这样声明里边参数只用传递对应的数据库的类型。

    ISqlStatementBulider  SqlBuilder = SqlBuilderFactory.GetInstance(DataBaseType.SqlServer);

    这样做的好处是:对于拓展我是支持的,对于外界调用者,他并不知道我是怎么实现的,我用什么方式实现的,以及怎么使用。他只需改变传递的枚举参数就可以了。

    如果说以后加入了Access类型的数据库,我只用在枚举类中加入Access的枚举,在实现文件夹中添加AccessSqlStatement.cs这样的一个类,让它实现ISqlSatementBulider接口定义的方法,这样就完成了。这样做我个人感觉拓展很容易。具体是什么设计模式,我也忘了,反正就是这个思想。

    接下来我们进入了第三层,也就是目前来说的最高层,也是算是应用层。

    这一层是 一个数据库工厂,用于执行sql语句。调用sql语句的工厂

    这是这一层的结构,首先是一个基类文件夹,一个实现文件夹,一个接口文件夹(目前为空尚未使用)

    在基类文件夹中声明了一个抽象类BasicsDatabase.cs这是一个基类,定义了需要实现的方法。(我仿照着.net core 下的asp.net mvc 项目里的StartUp.cs的构造函数,实现了一个我自己用的一个构造函数。读取json配置文件必须用的一个IConfigurationRoot )

     1     public abstract class BasicsDatabase
     2     {
     3         protected ISqlStatementBuilder SqlBuilder { get; set; }
     4         protected IDbConnection Connection { get; set; }
     5         public IConfigurationRoot Configuration { get; }
     6         protected IDbCommand Command { get; set; }
     7         protected BasicsDatabase()
     8         {
     9             var builder = new ConfigurationBuilder()
    10                 .SetBasePath(Directory.GetCurrentDirectory())
    11                 .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
    12             Configuration = builder.Build();
    13         }
    14      
    15         protected abstract string DatabaseConncetionString();
    16         public abstract List<T> GetAllInfo<T>() where T : new();
    17         public abstract bool Add(object data);
    18         public abstract bool Update(object data);
    19         public abstract bool Remove(object data);
    20     }
    BasicsDatabase.cs

    接下来是实现文件夹

    分别实现了三种不同的数据库,我这里只是实现了SqlServer的数据库类型。其他两个只是演示了怎么使用,以及怎么实现。

     1     public class SqlServerDatabase : BasicsDatabase
     2     {
     3         public SqlServerDatabase() : base()
     4         {
     5             base.Connection = new SqlConnection(DatabaseConncetionString());
     6             Connection.Open();
     7             base.Command = new SqlCommand();
     8             Command.Connection = base.Connection;
     9             //这里重要
    10             base.SqlBuilder = SqlBuilderFactory.GetInstance(DataBaseType.SqlServer);
    11         }
    12 
    13         public override List<T> GetAllInfo<T>()
    14         {
    15             Command.CommandText = SqlBuilder.ReadSqlString(new T());
    16             var Result = Command.ExecuteReader(CommandBehavior.SingleResult);
    17             var AllInfoList = new List<T>();
    18             while (Result.Read())
    19             {
    20                 var Record = (IDataRecord)Result;
    21                 AddOneObjectToList(ref AllInfoList, Record);
    22             }
    23 
    24             Result.Dispose();
    25             return AllInfoList;
    26         }
    27 
    28         private void AddOneObjectToList<T>(ref List<T> objectList, IDataRecord record) where T : new()
    29         {
    30             //获取所有的特性名称
    31             //查找record中的字段名称是否相同
    32             //如果相同将其值赋给该字段
    33             var PropertyNames = TypeHelperFactory.GetAllPropertyList(typeof(T));
    34             var Obj = new T();
    35             for (int i = 0; i < record.FieldCount; i++)
    36             {
    37                 var PropertyName = PropertyNames.FirstOrDefault(name => name == record.GetName(i));
    38                 if (PropertyName != null)
    39                 {
    40                     TypeHelperFactory.SetPropertyValue(Obj, PropertyName, record[i]);
    41                 }
    42 
    43             }
    44             objectList.Add(Obj);
    45         }
    46         public override bool Add(object data)
    47         {
    48             Command.CommandText = SqlBuilder.CreateSqlString(data);
    49             return Command.ExecuteNonQuery() > 0;
    50         }
    51         public override bool Remove(object data)
    52         {
    53             Command.CommandText = SqlBuilder.DeleteSqlString(data);
    54             return Command.ExecuteNonQuery() > 0;
    55         }
    56 
    57         public override bool Update(object data)
    58         {
    59             Command.CommandText = SqlBuilder.UpdateSqlString(data);
    60             return Command.ExecuteNonQuery() > 0;
    61         }
    62 
    63         protected override string DatabaseConncetionString()
    64         {
    65             return base.Configuration.GetConnectionString("DataContext");
    66         }
    67 
    68     }
    SqlServerDatabase.cs

    重点代码已经在注释中标注。这里给大家提一个醒在 24行的代码出,如果用.close()这个方法的话,add,和Update方法都没有问题,但是在Delete方法执行的时候会抛IDataReader没有关闭,请关闭后再使用的异常,用.dispose()这个方法可以解决。这是微软官网给的IDataReader样例https://docs.microsoft.com/en-us/dotnet/api/system.data.idatareader?view=netcore-1.1他用的是Close()这个方法,我刚开始也是用的是close(),这个方法,后来找了好久,改为dispose()就好了,具体原因还没有深入了解。

    这是其余两个只是演示了怎么使用

     1     public class MySqlDataBase : BasicsDatabase
     2     {
     3         /// <summary>
     4         /// 这是MySql数据库的实现方式
     5         /// 只用于演示并没有实现功能
     6         /// 时间:2017-5-12
     7         /// Author:曲
     8         /// </summary>
     9         public MySqlDataBase() : base()
    10         {
    11             base.Connection = new MySqlConnection();
    12             base.Connection.Open();
    13             base.Command = new MySqlCommand();
    14             base.Command.Connection = base.Connection;
    15             base.SqlBuilder = SqlBuilderFactory.GetInstance(DataBaseType.MySql);
    16         }
    17         public override bool Add(object data)
    18         {
    19             base.Command.CommandText = SqlBuilder.CreateSqlString(data);
    20             return base.Command.ExecuteNonQuery() > 0;
    21         }
    22 
    23         public override List<T> GetAllInfo<T>()
    24         {
    25             throw new NotImplementedException();
    26         }
    27 
    28         public override bool Remove(object data)
    29         {
    30             throw new NotImplementedException();
    31         }
    32 
    33         public override bool Update(object data)
    34         {
    35             throw new NotImplementedException();
    36         }
    37 
    38         protected override string DatabaseConncetionString()
    39         {
    40             throw new NotImplementedException();
    41         }
    42     }
    MySqlDataBase.cs
     1     /// <summary>
     2     /// Oracle数据库的实现方式
     3     /// 这是只是用于演示并没有真正实现
     4     /// 时间:2017-5-12
     5     /// Author:曲
     6     /// </summary>
     7     public class OracleDataBase : BasicsDatabase
     8     {
     9 
    10         public OracleDataBase() : base()
    11         {
    12             //base.Connection = new OracleConnection(DatabaseConncetionString());
    13             //Connection.Open();
    14             //base.Command = new OracleCommmand();
    15             //Command.Connection = Connection;
    16             //base.SqlBuilder = SqlBuilderFactory.GetInstance(DataBaseType.Oracle);
    17         }
    18         public override bool Add(object data)
    19         {
    20             Command.CommandText = SqlBuilder.CreateSqlString(data);
    21             return Command.ExecuteNonQuery() > 0;
    22         }
    23 
    24         public override List<T> GetAllInfo<T>()
    25         {
    26             throw new NotImplementedException();
    27         }
    28 
    29         public override bool Remove(object data)
    30         {
    31             throw new NotImplementedException();
    32         }
    33 
    34         public override bool Update(object data)
    35         {
    36             throw new NotImplementedException();
    37         }
    38 
    39         protected override string DatabaseConncetionString()
    40         {
    41             throw new NotImplementedException();
    42         }
    43     }
    OracleDataBase.cs

    这里还是挺丑的毕竟每个子类都要知道具体的实现步骤,准备把子类构造函数里的构造过程,放到抽象类中去,不知道能不能行的通,待明天尝试

    到了这里我的EF框架大致就模拟成功了,可以实现CRUD到数据库中。

    关于使用,我写了一个  使用说明.md文件。上边有配置步骤,可以一步步的配置然后就可以使用了。

    配置我自己定义的服务(这里实现的是sqlServer类型的数据库,如果实现了其他类型的,在这里改动一下就行了)

    1   //添加我自己的服务,这里声明的类型为基类型性,实现的是sqlServer的的数据库的类型。
    2             services.AddScoped<BasicsDatabase, SqlServerDatabase>();

    我在core环境下建了一个mvc项目

    在views文件夹中添加一个UserInfo文件夹

    里边有这么几个文件和用EF框架生成的一样,不过这里要进行手工的写,

    在Controller文件夹中添加一个mvc控制器 在控制器中是是这么用的

      1 using Microsoft.AspNetCore.Mvc;
      2 using MyEntityFrameWork.DateBaseFactory.BaseClass;
      3 using System;
      4 using System.Linq;
      5 using TestMyEntityFramework.Models;
      6 
      7 // For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
      8 
      9 namespace TestMyEntityFramework.Controllers
     10 {
     11     public class UserInfoController : Controller
     12     {
     13         private readonly BasicsDatabase _context;
     14         public UserInfoController(BasicsDatabase Database)
     15         {
     16             _context = Database;
     17         }
     18         
     19         // GET: /<controller>/
     20         public IActionResult Index()
     21         {
     22            
     23             return View(_context.GetAllInfo<Users>());
     24         }
     25         public IActionResult Create()
     26         {
     27             return View();
     28         }
     29         [HttpPost]
     30         [ValidateAntiForgeryToken]
     31         public IActionResult Create([Bind("ID,Name,pwd")] Users userInfo)
     32         {
     33             if (ModelState.IsValid)
     34             {
     35                 _context.Add(userInfo);     
     36                 return RedirectToAction("Index");
     37             }
     38             return View(userInfo);
     39         }
     40         public IActionResult Edit(int? id)
     41         {
     42             if (id == null)
     43             {
     44                 return NotFound();
     45             }
     46 
     47             var userInfo = _context.GetAllInfo<Users>().FirstOrDefault(u=>u.ID==id);
     48             if (userInfo == null)
     49             {
     50                 return NotFound();
     51             }
     52             return View(userInfo);
     53         }
     54 
     55         [HttpPost]
     56         [ValidateAntiForgeryToken]
     57         public IActionResult Edit(int id, [Bind("ID,Name,pwd")] Users userInfo)
     58         {
     59             if (id != userInfo.ID)
     60             {
     61                 return NotFound();
     62             }
     63 
     64             if (ModelState.IsValid)
     65             {
     66                 try
     67                 {
     68                     _context.Update(userInfo);
     69                    
     70                 }
     71                 catch 
     72                 {
     73                     if (!UserInfoExists(userInfo.ID))
     74                     {
     75                         return NotFound();
     76                     }
     77                     else
     78                     {
     79                         throw new Exception("数据更新失败");
     80                     }
     81                 }
     82                 return RedirectToAction("Index");
     83             }
     84             return View(userInfo);
     85         }
     86 
     87         public IActionResult Delete(int? id)
     88         {
     89             if (id == null)
     90             {
     91                 return NotFound();
     92             }
     93 
     94             var userInfo =  _context.GetAllInfo<Users>()
     95                 .SingleOrDefault(m => m.ID == id);
     96             if (userInfo == null)
     97             {
     98                 return NotFound();
     99             }
    100 
    101             return View(userInfo);
    102         }
    103 
    104         [HttpPost, ActionName("Delete")]
    105         [ValidateAntiForgeryToken]
    106         public IActionResult DeleteConfirmed(int id)
    107         {
    108             var userInfo =  _context.GetAllInfo<Users>().SingleOrDefault(m => m.ID == id);
    109 
    110             _context.Remove(userInfo);
    111             return RedirectToAction("Index");
    112         }
    113 
    114         public  IActionResult Details(int? id)
    115         {
    116             if (id == null)
    117             {
    118                 return NotFound();
    119             }
    120 
    121             var userInfo =  _context.GetAllInfo<Users>()
    122                 .SingleOrDefault(m => m.ID == id);
    123             if (userInfo == null)
    124             {
    125                 return NotFound();
    126             }
    127 
    128             return View(userInfo);
    129         }
    130         private bool UserInfoExists(int id)
    131         {
    132             return _context.GetAllInfo<Users>().Any(e => e.ID == id);
    133         }
    134     }
    135 }   
    UserInfoController.cs

     是不是和EF挺像的,就是GetAllList<T>这个方法有点丑,待我想到好方法,再改进一下,据说EF不是用反射,用的是泛型,我今天大致看了一下源码,确实是这样的,挺好的应该,毕竟反射对性能损失是较大的。

    待我研究出来头绪了,再和大家分享。

    git地址:https://github.com/1483523635/MyEntityFramework

     测试的Git地址:https://github.com/1483523635/UseMyEntityFrameWork

  • 相关阅读:
    JavaScript---动态加载script和style样式
    百度地图API----搜索地址,获取该点的位置坐标并转换成WebMercator
    ArcGIS api for JavaScript 3.27 FindTask查询功能
    Dojo.declare使用方法详解
    ArcGIS Desktop中为图像设置成不显示背景色
    网页导航条定位
    css3+JS实现幻灯片轮播图
    简单json---转树形json
    js中回调函数写法
    pom.xml文件报MavenArchiver错误 org.apache.maven.archiver.MavenArchiver.getManifest(org.apache.maven.project.MavenProject, org.apache.maven.archiver.MavenArchiveConfiguration)
  • 原文地址:https://www.cnblogs.com/qulianqing/p/6842714.html
Copyright © 2011-2022 走看看