前言

  在上一篇0_MVC+EF+Autofac(dbfirst)轻型项目框架_基本框架中,我已经介绍了这个轻型框架的层次结构,在下面的这篇文章中,我将以教师登陆功能为例,具体来扩充下我的core层的代码。

  在这之前,我想先补充讨论下是否有必要添加server层,因为看过不少别人的框架都有这一层。首先,server层在不同地方有着不同的解释。有个常听的词叫MVSC,这里所指的S虽然也是server的意思,但实现的功能更有点类似于我框架中的core,主要存放也是业务逻辑。但我看了别人框架上的server层,有些甚至已经直接继承自Controller类,一开始很不解,这样做让web层中的Controller颜面何存。但在深入了解了mvc的一些机制后觉得这样做也有道理(mvc在注册控制器时是遍历文件夹中的dll来的),把视图和控制器存放在了不同的程序集里,便于团队开发。但有些server层的作用更像是单纯为了给web(view)和core解耦或者说是改变依赖关系。具体我还真的没能力来讨论这么做有没有必要,别人这么做必然有别人的出发点和目的,但在我的轻量架构中还是没有引入server这个层,因为在一定程度上它只会增加框架整体的复杂性,“轻”还是主基调。

  同样,文中有问题的地方欢迎批评指正!谢谢!

创建过程

  1.首先数据表结构如下图

  1_MVC+EF+Autofac(dbfirst)轻型项目框架_core层(以登陆为例)

  表中ID是教师的GUID,TID才是用来登陆的唯一标示,PID是权限的标示,接下去讲权限判断时将会提到它。

  2.根据数据库生成edmx在Model层的Entity中

  3.在ICore中创建教师类接口,在Core中创建教师类

  接口中很简单,就一句话,定义了教师类的接口。

public partial interface ITeacher{}

  在Core中创建一个类用来实现ITeacher接口

    public partial class Teacher : BaseCore<Entity.Teacher>, ICore.ITeacher
    {
        public Teacher(DbContext dbContext)
        {
            db = dbContext;
        }
    }

  BaseCore是什么?不要惊慌。在上一篇中,我谈到了我将不引入DAL层来再次封装EF,但在EF中,有些操作比较复杂,例如修改删除等。如果每次使用时都要先查找再修改,要写很多重复代码,我的BaseCore是对这些方法的一些封装,虽然会造成一些代码的污染,但着实可以少写不少重复代码。也许会有人提出异议,这样的行为是否可以理解成是对EF的封装?我也不能完全否认,但我更愿意把它理解成业务层对于操作EF的帮助类:

    第一,相对于单独做一层来看,这样更“轻”

    第二,这样做放在业务上也更加合适,例如不需要去考虑“分页该不该放在DAL?”这类永远讨论不出正确答案的问题

    第三,维护更简单

    第四,既然是帮助类,那就提供了不用它的可能,觉得不爽不用它就是

  以下是BaseCore的代码,有点长。帮助类中借鉴了部分他人分享的代码,实在找不到出处了,这里表示感谢!

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Data.Entity;
  4 using System.Data.Entity.Infrastructure;
  5 using System.Linq;
  6 using System.Linq.Expressions;
  7 using System.Reflection;
  8 using System.Text;
  9 
 10 namespace EDUA_Core
 11 {
 12     /// <summary>
 13     /// 业务帮助父类
 14     /// </summary>
 15     /// <typeparam name="T">之类类型</typeparam>
 16     public class BaseCore<T> where T : class,new()
 17     {
 18         /// <summary>
 19         /// EF上下文对象
 20         /// </summary>
 21         protected DbContext db { get; set; }
 22 
 23         #region 1.0新增实体 + void Add(T model)
 24         /// <summary>
 25         /// 新增实体
 26         /// </summary>
 27         /// <param name="model">新增的实体</param>
 28         protected void Add(T model)
 29         {
 30             db.Set<T>().Add(model);
 31         }  
 32         #endregion
 33 
 34         #region 1.0.1新增实体并保存 + int AddAndSave(T model)
 35         /// <summary>
 36         /// 新增实体并保存
 37         /// </summary>
 38         /// <param name="model">新增的实体</param>
 39         /// <returns>受影响的行数</returns>
 40         protected int AddAndSave(T model)
 41         {
 42             Add(model);
 43             return db.SaveChanges();
 44         } 
 45         #endregion
 46 
 47         #region 2.0删除实体 + void Del(T model)
 48         /// <summary>
 49         /// 删除实体
 50         /// </summary>
 51         /// <param name="model">删除的实体</param>
 52         protected void Del(T model)
 53         {
 54             db.Set<T>().Attach(model);
 55             db.Set<T>().Remove(model);
 56         } 
 57         #endregion
 58 
 59         #region 2.0.1删除实体并保存 + int DelAndSave(T model)
 60         /// <summary>
 61         /// 删除实体并保存
 62         /// </summary>
 63         /// <param name="model">删除的实体</param>
 64         /// <returns>受影响的行数</returns>
 65         protected int DelAndSave(T model)
 66         {
 67             Del(model);
 68             return db.SaveChanges();
 69         } 
 70         #endregion
 71 
 72         #region 2.1根据条件删除 + void DelBy(Expression<Func<T, bool>> delWhere)
 73         /// <summary>
 74         /// 根据条件删除
 75         /// </summary>
 76         /// <param name="delWhere">条件</param>
 77         protected void DelBy(Expression<Func<T, bool>> delWhere)
 78         {
 79             //3.1查询要删除的数据
 80             List<T> listDeleting = db.Set<T>().Where(delWhere).ToList();
 81             //3.2将要删除的数据 用删除方法添加到 EF 容器中
 82             listDeleting.ForEach(u =>
 83             {
 84                 db.Set<T>().Attach(u);//先附加到 EF容器
 85                 db.Set<T>().Remove(u);//标识为 删除 状态
 86             });
 87         } 
 88         #endregion
 89 
 90         #region 2.1.1根据条件删除并保存 + int DelByAndSave(Expression<Func<T, bool>> delWhere)
 91         /// <summary>
 92         /// 根据条件删除并保存
 93         /// </summary>
 94         /// <param name="delWhere">条件</param>
 95         /// <returns>受影响的行数</returns>
 96         protected int DelByAndSave(Expression<Func<T, bool>> delWhere)
 97         {
 98             DelBy(delWhere);
 99             return db.SaveChanges();
100         } 
101         #endregion
102 
103         #region 3.0修改实体 + void Modify(T model, params string[] proNames)
104         /// <summary>
105         /// 修改,如:
106         /// T u = new T() { uId = 1, uLoginName = "asdfasdf" };
107         /// this.Modify(u, "uLoginName");
108         /// </summary>
109         /// <param name="model">要修改的实体对象</param>
110         /// <param name="proNames">要修改的 属性 名称</param>
111         protected void Modify(T model, params string[] proNames)
112         {
113             //4.1将 对象 添加到 EF中
114             DbEntityEntry entry = db.Entry<T>(model);
115             //4.2先设置 对象的包装 状态为 Unchanged
116             entry.State = (System.Data.Entity.EntityState)System.Data.EntityState.Unchanged;
117             //4.3循环 被修改的属性名 数组
118             foreach (string proName in proNames)
119             {
120                 //4.4将每个 被修改的属性的状态 设置为已修改状态;后面生成update语句时,就只为已修改的属性 更新
121                 entry.Property(proName).IsModified = true;
122             }
123         } 
124         #endregion
125 
126         #region 3.0.1修改和保存 + int ModifyAndSave(T model, params string[] proNames)
127         /// <summary>
128         /// 修改和保存,如:
129         /// T u = new T() { uId = 1, uLoginName = "asdfasdf" };
130         /// this.Modify(u, "uLoginName");
131         /// </summary>
132         /// <param name="model">要修改的实体对象</param>
133         /// <param name="proNames">要修改的 属性 名称</param>
134         /// <returns>受影响的行数</returns>
135         protected int ModifyAndSave(T model, params string[] proNames)
136         {
137             Modify(model, proNames);
138             return db.SaveChanges();
139         } 
140         #endregion
141 
142         #region 3.1批量修改 + void ModifyBy(T model, Expression<Func<T, bool>> whereLambda, params string[] modifiedProNames)
143         /// <summary>
144         /// 批量修改
145         /// </summary>
146         /// <param name="model">要修改的实体对象</param>
147         /// <param name="whereLambda">查询条件</param>
148         /// <param name="proNames">要修改的 属性 名称</param>
149         protected void ModifyBy(T model, Expression<Func<T, bool>> whereLambda, params string[] modifiedProNames)
150         {
151             //4.1查询要修改的数据
152             List<T> listModifing = db.Set<T>().Where(whereLambda).ToList();
153 
154             //获取 实体类 类型对象
155             Type t = typeof(T); // model.GetType();
156             //获取 实体类 所有的 公有属性
157             List<PropertyInfo> proInfos = t.GetProperties(BindingFlags.Instance | BindingFlags.Public).ToList();
158             //创建 实体属性 字典集合
159             Dictionary<string, PropertyInfo> dictPros = new Dictionary<string, PropertyInfo>();
160             //将 实体属性 中要修改的属性名 添加到 字典集合中 键:属性名  值:属性对象
161             proInfos.ForEach(p =>
162             {
163                 if (modifiedProNames.Contains(p.Name))
164                 {
165                     dictPros.Add(p.Name, p);
166                 }
167             });
168 
169             //4.3循环 要修改的属性名
170             foreach (string proName in modifiedProNames)
171             {
172                 //判断 要修改的属性名是否在 实体类的属性集合中存在
173                 if (dictPros.ContainsKey(proName))
174                 {
175                     //如果存在,则取出要修改的 属性对象
176                     PropertyInfo proInfo = dictPros[proName];
177                     //取出 要修改的值
178                     object newValue = proInfo.GetValue(model, null); //object newValue = model.uName;
179 
180                     //4.4批量设置 要修改 对象的 属性
181                     foreach (T usrO in listModifing)
182                     {
183                         //为 要修改的对象 的 要修改的属性 设置新的值
184                         proInfo.SetValue(usrO, newValue, null); //usrO.uName = newValue;
185                     }
186                 }
187             }
188         } 
189         #endregion
190 
191         #region 3.1.1批量修改并保存 + int ModifyByAndSave(T model, Expression<Func<T, bool>> whereLambda, params string[] modifiedProNames)
192         /// <summary>
193         /// 批量修改并保存
194         /// </summary>
195         /// <param name="model">要修改的实体对象</param>
196         /// <param name="whereLambda">查询条件</param>
197         /// <param name="proNames">要修改的 属性 名称</param>
198         /// <returns>受影响的行数</returns>
199         protected int ModifyByAndSave(T model, Expression<Func<T, bool>> whereLambda, params string[] modifiedProNames)
200         {
201             ModifyBy(model, whereLambda, modifiedProNames);
202             return db.SaveChanges();
203         } 
204         #endregion
205 
206         #region 4.0根据条件获取记录条数 + int GetCountBy(Expression<Func<T, bool>> whereLambda)
207         /// <summary>
208         /// 根据条件获取记录条数
209         /// </summary>
210         /// <returns>总记录条数</returns>
211         protected int GetCountBy(Expression<Func<T, bool>> whereLambda)
212         {
213             return db.Set<T>().Where(whereLambda).Count();
214         } 
215         #endregion
216 
217         #region 5.0获取所有记录 + List<T> GetAllList()
218         /// <summary>
219         /// 获取所有记录
220         /// </summary>
221         /// <returns>返回的集合</returns>
222         protected List<T> GetAllList()
223         {
224             return db.Set<T>().ToList();
225         } 
226         #endregion
227 
228         #region 5.1根据条件查询 + List<T> GetListBy(Expression<Func<T, bool>> whereLambda)
229         /// <summary>
230         /// 根据条件查询
231         /// </summary>
232         /// <param name="whereLambda">条件Lambda表达式</param>
233         /// <returns>返回的集合</returns>
234         protected List<T> GetListBy(Expression<Func<T, bool>> whereLambda)
235         {
236             return db.Set<T>().Where(whereLambda).ToList();
237         } 
238         #endregion
239 
240         #region 5.2根据条件 排序 和查询 + List<T> GetListBy<TKey>(Expression<Func<T, bool>> whereLambda, Expression<Func<T, TKey>> orderLambda, bool IsDes = false)
241         /// <summary>
242         /// 根据条件 排序 和查询
243         /// </summary>
244         /// <typeparam name="TKey">排序字段类型</typeparam>
245         /// <param name="whereLambda">查询条件 lambda表达式</param>
246         /// <param name="orderLambda">排序条件 lambda表达式</param>
247         /// // <param name="IsDes">是否逆序</param>
248         /// <returns>返回的集合</returns>
249         protected List<T> GetListBy<TKey>(Expression<Func<T, bool>> whereLambda, Expression<Func<T, TKey>> orderLambda, bool IsDes = false)
250         {
251             if(IsDes)
252                 return db.Set<T>().Where(whereLambda).OrderByDescending(orderLambda).ToList();
253             return db.Set<T>().Where(whereLambda).OrderBy(orderLambda).ToList();
254         } 
255         #endregion
256 
257         #region 5.3分页查询 + List<T> GetPagedList<TKey>(int pageIndex, int pageSize, Expression<Func<T, bool>> whereLambda, Expression<Func<T, TKey>> orderBy, bool IsDes = false)
258         /// <summary>
259         /// 分页查询
260         /// </summary>
261         /// <param name="pageIndex">页码</param>
262         /// <param name="pageSize">页容量</param>
263         /// <param name="whereLambda">条件 lambda表达式</param>
264         /// <param name="orderBy">排序 lambda表达式</param>
265         /// <param name="IsDes">是否逆序</param>
266         /// <returns>返回的集合</returns>
267         protected List<T> GetPagedList<TKey>(int pageIndex, int pageSize, Expression<Func<T, bool>> whereLambda, Expression<Func<T, TKey>> orderBy, bool IsDes = false)
268         {
269             if (IsDes)
270                 return db.Set<T>().Where(whereLambda).OrderByDescending(orderBy).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
271             return db.Set<T>().Where(whereLambda).OrderBy(orderBy).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
272         } 
273         #endregion
274 
275     }
276 }
View Code

相关文章: