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

 

posted @ 2017-05-17 21:40  Bluto  阅读(1040)  评论(1编辑  收藏  举报