欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

三层架构搭建(asp.net mvc + ef)

程序员文章站 2022-05-04 14:16:59
第一次写博客,想了半天先从简单的三层架构开始吧,希望能帮助到你! 简单介绍一下三层架构, 三层架构从上到下分:表现层(UI),业务逻辑层(BLL),数据访问层(DAL)再加上数据模型(Model),用ef访问数据库,Model也就是与数据库表映射的实体。废话少说,上代码。 Model层 为方便说明, ......

第一次写博客,想了半天先从简单的三层架构开始吧,希望能帮助到你!

简单介绍一下三层架构, 三层架构从上到下分:表现层(ui),业务逻辑层(bll),数据访问层(dal)再加上数据模型(model),用ef访问数据库,model也就是与数据库表映射的实体。废话少说,上代码。

  • model层

为方便说明,新建一个实体模型userinfo,数据库表中应该对应一个userinfo表,至于怎样建立表,有多种方式,用ef来建立表比较方便。具体怎样用ef访问数据库,后续会在其他文章中解释,敬请关注。

1     public class userinfo
2     {
3         public int id { get; set; }
4         public string name { get; set; }
5         public short age { get; set; }
6     }
  • dal层

首先设计通用的crud基接口ibasedal,作为通用的数据库访问通道。

1     public interface ibasedal<t> where t : class,new()
2     {
3         void add(t entity);
4         void delete(t entity);
5         void update(t entity);
6         iqueryable<t> getentities(expression<func<t, bool>> expression);
7         iqueryable<t> getentitiesbypage<tkey>(int pagesize, int pageindex, bool isasc, expression<func<t, tkey>> keyselector, expression<func<t, bool>> expression);
8         bool savechanges();
9     }

以userinfo实体为例,继承ibasedal接口

    public interface iuserinfodal : ibasedal<userinfo>
    {

    }

接口设计完成,设计通用基类,这里存在变化点,本例用ef实现,如果以后通过其他实体框架或者直接通过ado.net访问数据库,只需要改动这个类。

    public class basedal<t> where t : class,new()
    {
        private dbcontext dbcontext = dbcontextfactory.dbcontext;

        public void add(t entity)
        {
            dbcontext.set<t>().add(entity);
        }

        public void delete(t entity)
        {
            dbcontext.entry(entity).state = entitystate.deleted;
        }

        public void update(t entity)
        {
            dbcontext.entry(entity).state = entitystate.modified;
        }

        public iqueryable<t> getentities(expression<func<t, bool>> expression)
        {
            return dbcontext.set<t>().where(expression);
        }

        public iqueryable<t> getentitiesbypage<tkey>(int pagesize, int pageindex, bool isasc, expression<func<t, tkey>> keyselector, expression<func<t, bool>> expression)
        {
            if (isasc)  //升序
            {
                return dbcontext.set<t>().where(expression).orderby(keyselector).skip((pageindex - 1) * pagesize).take(pagesize);
            }
            else        //降序
            {
                return dbcontext.set<t>().where(expression).orderbydescending(keyselector).skip((pageindex - 1) * pagesize).take(pagesize);
            }
        }

        public bool savechanges()
        {
            return dbcontext.savechanges() > 0;
        }
    }
    public static class dbcontextfactory
    {
        public static dbcontext dbcontext
        {
            get
            {
                dbcontext dbcontext = callcontext.getdata("dbcontext") as dbcontext;
                if (dbcontext == null)
                {
                    dbcontext = new modelcontainer();
                    callcontext.setdata("dbcontext", dbcontext);
                }
                return dbcontext;
            }
        }
    }

接下来实现具体的实体数据访问层,以userinfodal为例,其余类似。

    public class userinfodal : basedal<userinfo>, iuserinfodal
    {

    }
  • bll层

首先像dal层一样,定义通用接口。

    public interface ibaseservice<t> where t : class,new()
    {
        void add(t entity);
        void delete(t entity);
        void update(t entity);
        iqueryable<t> getentities(expression<func<t, bool>> expression);
        iqueryable<t> getentitiesbypage<tkey>(int pagesize, int pageindex, bool isasc, expression<func<t, tkey>> keyselector, expression<func<t, bool>> expression);
        bool savechanges();
    }

通用基类,注意通用基类不需要实现上面的接口

    public class baseservice<t> where t : class,new()
    {
        private basedal<t> basedal = new basedal<t>();

        public void add(t entity)
        {
            basedal.add(entity);
        }

        public void delete(t entity)
        {
            basedal.delete(entity);
        }

        public void update(t entity)
        {
            basedal.update(entity);
        }

        public iqueryable<t> getentities(expression<func<t, bool>> expression)
        {
            return basedal.getentities(expression);
        }

        public iqueryable<t> getentitiesbypage<tkey>(int pagesize, int pageindex, bool isasc, expression<func<t, tkey>> keyselector, expression<func<t, bool>> expression)
        {
            return basedal.getentitiesbypage(pagesize, pageindex, isasc, keyselector, expression);
        }

        public bool savechanges()
        {
            return basedal.savechanges();
        }
    }

接下来是userinfoservice

    public class userinfoservice : baseservice<userinfo>, ibaseservice<userinfo>
    {

    }

至此,所有底层代码完成,顶层的ui层调用不在赘述了,这里附上源码下载地址

链接:https://pan.baidu.com/s/1itw5xkbyb1onkqdfuwjvmw
提取码:ye0n

说明:源码中model层中采用的ef的model first方式创建数据库,下载以后不能直接运行,可以将model程序集中的model.edmx.sql在sqlserver创建数据库,以database first方式重新创建model程序集,可以正常运行。