一种基于EF+MVC的小型系统快速开发架构

             在一般的Web系统中,主要工作无外乎增删改查。事实上百分之八十的系统所做的工作也不外如是,不存在非常复杂的逻辑。只是数据的处理与展现。经过多次调整,整理出了一套基于EF+MVC的小型系统快速开发架构。主要思想是利用EF和泛型编程,将大部分的常用数据处理封装到DAL层中,在控制器中直接调用,大大提高开发速度。就目前来说,非常简洁实用。

           1、依靠主外键关系编织数据

            数据表之间是否应该存在关系曾引起很多人的争论。就小型系统来说,创建关系可以明晰实体之间的关系,而且可以由数据库来维护数据的完整性。虽然在更新和删除的时候存在一些限制,但对于缺少专门数据库开发人员甚至是一个人进行开发情况来说,是利大于弊的。
          外键关系在EF中被映射为导航属性,使得使用数据非常的便捷。更现实的说,基于外键关系映射的实体关系为泛型编程的使用提供了得天独厚的条件。
          假设存在:老师  班级  学生三个存在关系的实体,那依赖EF和关系,我们很容易进行类似的筛选:老师所教的班级的所有学生=>老师.班级s.学生s,而且在一个数据库中,不允许存在没有外键关系的独立实体,两个实体之间,总可以通过某种关系联系起来。这样就避免在联合查询中频繁使用丑陋的linq语句,从而为抽象提供了可能性。

          2、泛型委托

           依赖linq的数据查询毫无例外的都是一种“现场编码”,作用域收到了限制。而这里我们使用系统自带的Fun<T,T>来作为筛选或者查询的参数,从而把外部条件和框架分离开来。比如我们想筛选某种符合条件的实体数量,可以这样写:

        /// <summary>
        /// 读取实体数量
        /// </summary>
        /// <param name="exp">筛选委托</param>
        /// <returns>实体数量</returns
        public static int GetEntitiesCount(Func<T, bool> exp)
        {
            using (var db = new CapitalConstructionEntities())
            {
                return db.Set<T>().Where(exp).Count();
            }
        }
       这样就把筛选条件和筛选框架方法分离开。

      3、懒加载与include

      EF默认是懒加载的,如果你要加载关联实体,必须制定关联的导航属性名。导航属性名可以在一个维度上不断往下“点”,比如“老师.学生.父母.工作单位",会把这四个表中的相关数据全都查出来。
     比如想查询一个带”一维“关联属性的实体,代码如下:

      /// <summary>
        /// 获得一个实体(带一维导航属性)
        /// </summary>
        /// <param name="exp">筛选委托</param>
        /// <param name="firstInclude">一维导航属性字符串</param>
        /// <returns>单一实体或Null</returns>
        public static T GetEntity(Func<T, bool> exp, string firstInclude)
        {
            using (var db = new CapitalConstructionEntities())
            {
                return db.Set<T>().Include(firstInclude).Where(exp).SingleOrDefault();
            }
        }

    4、投影与匿名属性

      我们经常需要查询实体的一部分而不是全部。而这个投影产生的新匿名类型,往往是当视图模型使用的。此时就可以利用匿名属性,利用Fun<T,dynamic>泛型委托来返回匿名属性,获取一个实体投影的代码如下:

        /// <summary>
        /// 获得一个实体的投影
        /// </summary>
        /// <param name="exp">筛选委托</param>
        /// <param name="selector">投影委托</param>
        /// <returns>dynamic</returns>
        public static dynamic GetPartEntity(Func<T, bool> exp, Func<T, dynamic> selector)
        {
            using (var db = new CapitalConstructionEntities())
            {
                return db.Set<T>().Where(exp).Select(selector).SingleOrDefault();
            }
        }

       总结:依靠上述思想和方法,可以将小型系统开发所需要的一些常用数据操作全部封装起来,比如读取,分页,投影,带导航属性对应操作,删除,更新等。从而在控制器中可以非常简单的使用DAL中的方法,也许有人说你没有BLL层,确实,这种架构下是没有BLL层。但是在一个简单的系统中,如果BLL层的作用仅仅是转发控制器的请求,在BLL中原封不动的调用DAL层的方法,BLL层的意义并不太大。三层并不是必须的,可以根据需要进行取舍。
       DAL中每个实体都有一个对应的dao类,其代码类似:

  public class ContractDao:Dao<Contract>
    {
    }
   在继承时注入了实体类型。

  在控制器中我们可以进行如下调用:

</pre><pre name="code" class="csharp">   //判断名称是否存在
        public string ContractExist(string keyWords)
        {
            if (ContractDao.GetEntitiesCount(c => c.Contract_Name == keyWords) >= 1)
            {
                var con = ContractDao.GetEntity(c => c.Contract_Name == keyWords);
                return JsonConvert.SerializeObject(new { Success = true, Message = con.Contract_ID });
            }
            return JsonConvert.SerializeObject(new { Success = false, Message = "该名称不存在!" });
        }
     在控制器中直接调用方法进行业务处理,是不是很简单!
     如果控制器中有重复的逻辑,也可以提升到基控制器中,也实现了复用。 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值