zoukankan      html  css  js  c++  java
  • 三层架构搭建(asp.net mvc + ef)

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

    简单介绍一下三层架构, 三层架构从上到下分:表现层(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程序集,可以正常运行。

  • 相关阅读:
    loadView和viewDidLoad的官方API的一些解释
    面向对象IOS编程中的聚合与耦合
    史上最全的iOS面试题及答案
    oc的基本数据的转换
    NSDateFormatter时间函数
    图片点击放大,再次点击返回原视图.完美封装,一个类一句代码即可调用.IOS完美实现
    同一ViewController内如果有两处AlertView要用代理Delegate怎么写法
    简单实现---下拉刷新 --使用UITableViewController中的refreshControl属性
    简单实现---上拉加载刷新---
    洛谷2863 [Usaco06JAN]牛的舞会
  • 原文地址:https://www.cnblogs.com/chirsli/p/10533169.html
Copyright © 2011-2022 走看看