[MVC学习笔记]1.项目结构搭建及单个类在各个层次中的实现

      新人刚开始学习ASP.NET MVC,若有不足之处希望能得到您的指点,不胜感激!

 

       先来一张项目的层级结构图:

image

      Model:模型层,主要是各种类型、枚举以及ORM框架,框架完成数据库和实体类的映射。项目中选用了微软的开源ORM框架 EntityFramework 6.0 (以下简称EF),数据库则选择了微软的轻量级数据库SQL Server Compact 4.0本地数据库(简称Compact),Compact对EF支持比较完美,又属于文档型数据库,部署起来比较简洁。

      DAL:数据访问层,主要是对数据库的操作层,为业务逻辑层或表示层提供数据服务。

      IDAL:数据访问接口层,是数据访问层的接口,降低耦合。

      DALFactory:数据会话层,封装了所有数据操作类实例的创建,将数据访问层与业务逻辑层解耦。

      BLL:业务逻辑层,主要负责对数据层的操作,把一些数据层的操作进行组合以完成业务的需要。

      IBLL:业务逻辑接口层,业务逻辑层的接口,降低耦合。

      WebApp:表现层,是一个ASP.NET MVC项目,完成具体网站的实现。

      Common:通用层,用来存放一些工具类。

      下面是各个层级之间具体的实现,首先创建以 项目名.层级名 命名的各个层次,除WebApp层为ASP.NET MVC项目外,其余均创建为类库项目。

image

     

 

 

模型层的构建

      先建立模型层,新建ASP.NET 实体数据模型,关联到已经设计好的数据库,EF自动完成模型类的创建。

 

image

数据访问层的构建

      DAL层中,我们首先需要一个方法来获取单例的EF数据操纵上下文对象,以保证每个用户访问时只有使用一个上下文对象对数据库进行操作。DbContextFactory.cs

using System.Data.Entity;
using System.Runtime.Remoting.Messaging;
using PMS.Model;namespace PMS.DAL
{public class DbContextFactory{/// <summary>/// 负责创建EF数据操作上下文实例,必须保证线程内唯一/// </summary>public static DbContext CreateContext(){DbContext dbContext = (DbContext)CallContext.GetData("dbContext");if (dbContext != null) return dbContext;dbContext = new PMSEntities();CallContext.SetData("dbContext", dbContext);return dbContext;}}
}

      为User类创建DAL层,实现查询、分页查询、增加、删除和修改这五个基本的方法:UserDAL.cs

using System;
using System.Data.Entity;
using System.Linq;
using PMS.IDAL;namespace PMS.DAL
{public partial class UserDal 
    {public DbContext DbEntities = DbContextFactory.CreateContext();/// <summary>/// 查询过滤/// </summary>/// <param name="whereLamada">过滤条件Lambda表达式</param>/// <returns>实体集合</returns>public IQueryable<UserDal> LoadEntities(System.Linq.Expressions.Expression<Func<UserDal, bool>> whereLamada){return DbEntities.Set<UserDal>().Where(whereLamada);}/// <summary>/// 分页查询/// </summary>/// <typeparam name="TS">排序类型</typeparam>/// <param name="pageIndex">查询的页码</param>/// <param name="pageSize">每页显示的数目</param>/// <param name="totalCount">符合条件的总行数</param>/// <param name="whereLambda">过滤条件Lambda表达式</param>/// <param name="orderbyLambda">排序Lambda表达式</param>/// <param name="isAsc">排序方向</param>/// <returns>实体集合</returns>public IQueryable<UserDal> LoadPageEntities<TS>(int pageIndex, int pageSize, out int totalCount, System.Linq.Expressions.Expression<Func<UserDal, bool>> whereLambda, System.Linq.Expressions.Expression<Func<UserDal, TS>> orderbyLambda, bool isAsc){var temp = DbEntities.Set<UserDal>().Where(whereLambda);totalCount = temp.Count();temp = isAsc ? temp.OrderBy(orderbyLambda).Skip((pageIndex - 1) * pageSize).Take(pageSize) : temp.OrderByDescending(orderbyLambda).Skip((pageIndex - 1) * pageSize).Take(pageSize);return temp;}/// <summary>/// 删除数据/// </summary>/// <param name="entity">待删数据</param>/// <returns>删除结果</returns>public bool DeleteEntity(UserDal entity){DbEntities.Entry(entity).State = EntityState.Deleted;return true;}/// <summary>/// 编辑数据/// </summary>/// <param name="entity">待编辑数据</param>/// <returns>编辑结果</returns>public bool EditEntity(UserDal entity){DbEntities.Entry(entity).State = EntityState.Modified;return true;}/// <summary>/// 添加数据/// </summary>/// <param name="entity">待添加数据</param>/// <returns>已添加数据</returns>public UserDal AddEntity(UserDal entity){entity = DbEntities.Set<UserDal>().Add(entity);return entity;}       }
}

注:这里的增删改操作并不即时进行,而是在封装在数据会话层中,以实现工作单元模式,提高数据库的操作效率。

      考虑到每个类都需要实现相同的数据操作,我们可以将以上方法封装到一个泛型基类中,各类型只需要继承泛型基类就可以实现以上方法:BaseDal.cs

using System;
using System.Data.Entity;
using System.Linq;namespace PMS.DAL
{public class BaseDal<T> where T:class ,new(){public DbContext DbEntities = DbContextFactory.CreateContext();/// <summary>/// 查询过滤/// </summary>/// <param name="whereLamada">过滤条件Lambda表达式</param>/// <returns>实体集合</returns>public IQueryable<T> LoadEntities(System.Linq.Expressions.Expression<Func<T, bool>> whereLamada){return DbEntities.Set<T>().Where(whereLamada);}/// <summary>/// 分页查询/// </summary>/// <typeparam name="TS">排序类型</typeparam>/// <param name="pageIndex">查询的页码</param>/// <param name="pageSize">每页显示的数目</param>/// <param name="totalCount">符合条件的总行数</param>/// <param name="whereLambda">过滤条件Lambda表达式</param>/// <param name="orderbyLambda">排序Lambda表达式</param>/// <param name="isAsc">排序方向</param>/// <returns>实体集合</returns>public IQueryable<T> LoadPageEntities<TS>(int pageIndex, int pageSize, out int totalCount, System.Linq.Expressions.Expression<Func<T, bool>> whereLambda, System.Linq.Expressions.Expression<Func<T, TS>> orderbyLambda, bool isAsc){var temp = DbEntities.Set<T>().Where(whereLambda);totalCount = temp.Count();temp = isAsc ? temp.OrderBy(orderbyLambda).Skip((pageIndex - 1) * pageSize).Take(pageSize) : temp.OrderByDescending(orderbyLambda).Skip((pageIndex - 1) * pageSize).Take(pageSize);return temp;}/// <summary>/// 删除数据/// </summary>/// <param name="entity">待删数据</param>/// <returns>删除结果</returns>public bool DeleteEntity(T entity){DbEntities.Entry(entity).State = EntityState.Deleted;return true;}/// <summary>/// 编辑数据/// </summary>/// <param name="entity">待编辑数据</param>/// <returns>编辑结果</returns>public bool EditEntity(T entity){DbEntities.Entry(entity).State = EntityState.Modified;return true;}/// <summary>/// 添加数据/// </summary>/// <param name="entity">待添加数据</param>/// <returns>已添加数据</returns>public T AddEntity(T entity){entity = DbEntities.Set<T>().Add(entity);//DbEntities.SaveChanges();return entity;}}
}

UserDal继承BaseDal

using PMS.IDAL;
using PMS.Model;namespace PMS.DAL
{public partial class UserDal : BaseDal<User>{}
}

数据访问接口层的构建

      然后我们建立相应的IbaseDal接口和IUserDal接口,并且使UserDal类实现IUserDal接口

IBaseDal:

using System;
using System.Linq;namespace PMS.IDAL
{public interface IBaseDal<T> where T:class,new(){IQueryable<T> LoadEntities(System.Linq.Expressions.Expression<Func<T, bool>> whereLamada);IQueryable<T> LoadPageEntities<s>(int pageIndex, int pageSize, out int totalCount,System.Linq.Expressions.Expression<Func<T, bool>> whereLambda,System.Linq.Expressions.Expression<Func<T, s>> orderbyLambda, bool isAsc);bool DeleteEntity(T entity);bool EditEntity(T entity);T AddEntity(T entity);}
}

IUserDal:

using PMS.Model;namespace PMS.IDAL
{public partial interface IUserDal:IBaseDal<User>{}
}

UserDal实现IUserDal接口:

public partial class UserDal : BaseDal<User>,IUserDal

数据会话层的构建

抽象工厂类AbstractFactory:

using System.Configuration;
using System.Reflection;
using PMS.IDAL;namespace PMS.DALFactory
{public partial class AbstractFactory{//读取保存在配置文件中的程序集名称与命名空间名private static readonly string AssemblyPath = ConfigurationManager.AppSettings["AssemblyPath"];private static readonly string NameSpace = ConfigurationManager.AppSettings["NameSpace"];/// <summary>/// 获取UserDal的实例/// </summary>/// <returns></returns>public static IUserDal CreateUserInfoDal(){var fullClassName = NameSpace + ".UserInfoDal";return CreateInstance(fullClassName) as IUserDal;}/// <summary>/// 通过反射获得程序集中某类型的实例/// </summary>/// <param name="className"></param>/// <returns></returns>private static object CreateInstance(string className){var assembly = Assembly.Load(AssemblyPath);return assembly.CreateInstance(className);}}
}

数据会话类DbSession:

using System.Data.Entity;
using PMS.IDAL;
using PMS.DAL;namespace PMS.DALFactory
{public partial class DbSession:IDbSession{public DbContext Db{get { return DbContextFactory.CreateContext(); }}private IUserDal _userDal;public IUserDal UserDal{get { return _userDal ?? (_userDal = AbstractFactory.CreateUserInfoDal()); }set { _userDal = value; }}/// <summary>/// 工作单元模式,统一保存数据/// </summary>/// <returns></returns>public bool SaveChanges(){return Db.SaveChanges() > 0;}}
}

 

 

 

业务逻辑层的构建

业务类基类BaseService

using System;
using System.Linq;
using System.Linq.Expressions;
using PMS.DALFactory;
using PMS.IDAL;namespace PMS.BLL
{public abstract class BaseService<T> where T:class,new(){public IDbSession CurrentDbSession{get{return new DbSession();}}public IBaseDal<T> CurrentDal { get; set; }public abstract void SetCurrentDal();public BaseService(){SetCurrentDal();//子类一定要实现抽象方法,以指明当前类的子类类型。
       }/// <summary>/// 查询过滤/// </summary>/// <param name="whereLambda"></param>/// <returns></returns>public IQueryable<T> LoadEntities(Expression<Func<T, bool>> whereLambda){return CurrentDal.LoadEntities(whereLambda);}/// <summary>/// 分页/// </summary>/// <typeparam name="s"></typeparam>/// <param name="pageIndex"></param>/// <param name="pageSize"></param>/// <param name="totalCount"></param>/// <param name="whereLambda"></param>/// <param name="orderbyLambda"></param>/// <param name="isAsc"></param>/// <returns></returns>public IQueryable<T> LoadPageEntities<s>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> whereLambda,Expression<Func<T, s>> orderbyLambda, bool isAsc){return CurrentDal.LoadPageEntities<s>(pageIndex, pageSize, out totalCount, whereLambda, orderbyLambda, isAsc);}/// <summary>/// 删除/// </summary>/// <param name="entity"></param>/// <returns></returns>public bool DeleteEntity(T entity){CurrentDal.DeleteEntity(entity);return CurrentDbSession.SaveChanges();}/// <summary>/// 编辑/// </summary>/// <param name="entity"></param>/// <returns></returns>public bool EditEntity(T entity){CurrentDal.EditEntity(entity);return CurrentDbSession.SaveChanges();}/// <summary>/// 添加数据/// </summary>/// <param name="entity"></param>/// <returns></returns>public T AddEntity(T entity){CurrentDal.AddEntity(entity);CurrentDbSession.SaveChanges();return entity;}}
}

 

UserService类:

using PMS.IBLL;
using PMS.Model;namespace PMS.BLL
{public partial class UserService : BaseService<User>{public override void SetCurrentDal(){CurrentDal = CurrentDbSession.UserDal;}}
}

 

 

 

业务逻辑接口层的构建

      直接建立对应的接口并使用UserService类实现IUserService接口

IBaseService接口:

using System;
using System.Linq;
using System.Linq.Expressions;
using PMS.IDAL;namespace PMS.IBLL
{public interface IBaseService<T> where T : class,new(){IDbSession CurrentDbSession { get; }IBaseDal<T> CurrentDal { get; set; }void SetCurrentDal();IQueryable<T> LoadEntities(Expression<Func<T, bool>> whereLambda);IQueryable<T> LoadPageEntities<s>(int pageIndex, int pageSize, out int totalCount,Expression<Func<T, bool>> whereLambda,Expression<Func<T, s>> orderbyLambda, bool isAsc);bool DeleteEntity(T entity);bool EditEntity(T entity);T AddEntity(T entity);}
}

IUserService接口:

using PMS.Model;namespace PMS.IBLL
{public partial interface IUserService:IBaseService<User>{}
}

使用UserService类实现IUserService接口:

public partial class UserService : BaseService<User>, IUserService

 

 

以上我们就完成了整个框架中关于User类的各层次的实现。

转载于:https://www.cnblogs.com/WayneShao/p/5876880.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/542568.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

日期getUTCSeconds()方法以及JavaScript中的示例

JavaScript日期getUTCSeconds()方法 (JavaScript Date getUTCSeconds() method) getUTCSeconds() method is a Dates class method and it is used to get seconds from the current time according to the UTC (Universal time coordinated). getUTCSeconds()方法是Date的类方…

dedecms 在模板里引入php文件夹,dedecms如何添加并引入php文件

前言&#xff1a;有些时候我们需要创建一些单独的PHP文件&#xff0c;但是随便放入的PHP文件是不能够编译织梦 dedecms的标签的&#xff0c;所以我们需要引入织梦标签的编译引擎方案。例如&#xff0c;我们在根目录创建 example.php&#xff0c;代码如下&#xff1a;<?php …

mybatisplus代码生成器_想做时间管理大师?你可以试试Mybatis Plus代码生成器

1. 前言对于写Crud的老司机来说时间非常宝贵&#xff0c;一些样板代码写不但费时费力&#xff0c;而且枯燥无味。经常有小伙伴问我&#xff0c;胖哥你怎么天天那么有时间去搞新东西&#xff0c;透露一下秘诀呗。好吧&#xff0c;今天就把Mybatis-plus的代码生成器分享出来&…

安装Oracle 11g RAC R2 之Linux DNS 配置

Oracle 11g RAC 集群中引入了SCAN(Single Client Access Name)的概念&#xff0c;也就是指集群的单客户端访问名称。SCAN 这个特性为客户端提供了单一的主机名&#xff0c;用于访问集群中运行的 Oracle 数据库。如果您在集群中添加或删除节点&#xff0c;使用 SCAN 的客户端无需…

c++ websocket客户端_websocket使用

websocket使用一、介绍在项目开发过程中&#xff0c;很多时候&#xff0c;我们不可避免的需要实现的一个功能&#xff1a; 服务端实时发送信息给客户端。比如实时公告、实时订单通知、实时报警推送等等&#xff0c;登录后的客户端需要知道与它相关的实时信息&#xff0c;以便进…

汉子编码比字母编码长_字母/博客作者编码问题(使用动态编程)

汉子编码比字母编码长Problem statement: 问题陈述&#xff1a; Shivang is a blog writer and he is working on two websites simultaneously. He has to write two types of blogs which are: Shivang是一位博客作家&#xff0c;他同时在两个网站上工作。 他必须写两种类型…

php parent报错,mac brew 安装php扩展报错:parent directory is world writable but not sticky

$ brew install php70-mcrypt报错&#xff1a;Error: parent directory is world writable but not sticky搜索到github的答案https://github.com/Homebrew/legacy-homebrew/issues/40345原因&#xff1a;/tmp目录权限不对$ ls -ld /private/tmp打印出来 /private/tmp 被标黄了…

在cordova中使用HTML5的多文件上传

2019独角兽企业重金招聘Python工程师标准>>> 我们先看看linkface给开放的接口&#xff1a; 字段类型必需描述api_idstring是API 账户api_secretstring是API 密钥selfie_filefile见下方注释需上传的图片文件 1&#xff0c;上传本地图片进行检测时选取此参数selfie_ur…

python dataframe切片_python pandas dataframe 行列选择,切片操作方法

SQL中的select是根据列的名称来选取&#xff1b;Pandas则更为灵活&#xff0c;不但可根据列名称选取&#xff0c;还可以根据列所在的position&#xff08;数字&#xff0c;在第几行第几列&#xff0c;注意pandas行列的position是从0开始&#xff09;选取。相关函数如下&#xf…

php根据设备判断访问,PHP判断设备访问来源

/*** 判断用户请求设备是否是移动设备* return bool*/function isMobile() {//如果有HTTP_X_WAP_PROFILE则一定是移动设备if (isset($_SERVER[HTTP_X_WAP_PROFILE])) {return true;}//如果via信息含有wap则一定是移动设备,部分服务商会屏蔽该信息if (isset($_SERVER[HTTP_VIA])…

机器学习 深度学习 ai_如何学习机器学习和人工智能?

机器学习 深度学习 aiSTRATEGY 战略 Learn theory practical aspects. 学习理论和实践方面的知识。 (At first get an overview of what you are going to learn). (首先获得要学习的内容的概述)。 Gain a good hold/insight on each concept. 掌握/理解每个概念。 If you …

linux常用命令和配置

2019独角兽企业重金招聘Python工程师标准>>> 启动php&#xff1a; /etc/init.d/php-fpm restart 查看PHP运行目录&#xff1a; which php /usr/bin/php 查看php-fpm进程数&#xff1a; ps aux | grep -c php-fpm 查看运行内存 /usr/bin/php -i|grep mem iptables如…

centos7时间同步_centos 8.x系统配置chrony时间同步服务

centos 8.x系统配置chrony时间同步服务CentOS 7.x默认使用的时间同步服务为ntp服务&#xff0c;但是CentOS 8开始在官方的仓库中移除了ntp软件&#xff0c;换成默认的chrony进行时间同步的服务&#xff0c;chrony既可以作为客户端向其他时间服务器发送时间同步请求&#xff0c;…

php可以用scanf,C/C++中 使用scanf和printf如何读入输出double型数据。

黄舟2017-04-17 13:47:232楼注意scanf函数和printf函数是不同寻常的函数&#xff0c;因为它们都没有将函数的参数限制为固定数量。scanf函数和printf函数又可变长度的参数列表。当调用带可变长度参数列表的函数时&#xff0c;编译器会安排float参数自动转换成为double类型&…

ICWAI和ICWA的完整形式是什么?

ICWAI / ICWA&#xff1a;印度成本与工程会计师协会/印度儿童福利法 (ICWAI / ICWA: Institute of Cost and Works Accountants of India / Indian Child Welfare Act) 1)ICWAI&#xff1a;印度成本与工程会计师协会 (1) ICWAI: Institute of Cost and Works Accountants of In…

深入研究java.lang.Runtime类【转】

转自&#xff1a;http://blog.csdn.net/lastsweetop/article/details/3961911 目录(?)[-] javalang 类 RuntimegetRuntimeexitaddShutdownHookremoveShutdownHookhaltrunFinalizersOnExitexecexecexecexecexecexecavailableProcessorsfreeMemorytotalMemorymaxMemorygcrunFina…

java队列实现限流,java中应对高并发的两种策略

目的&#xff1a;提高可用性通过ExecutorService实现队列泄洪//含有20个线程的线程池private ExecutorService executorService Executors.newFixedThreadPool(20);将有并发压力的下游代码放入到线程池的submit方法中&#xff0c;如下&#xff1a;//同步调用线程池的submit方法…

crontab 日志_liunx 中定时清理过期日志文件

问题描述经常遇到日志文件过多&#xff0c;占用大量磁盘空间&#xff0c;需要定期删除过期日志。问题涉及方面删除过期日志的脚本。定时任务删除任务脚本先查询到过期的日志文件&#xff0c;然后删除。语法find path -option [ -print ] [ -exec -ok command ] …

JavaScript | 数组的常用属性和方法

JavaScript的通用属性和数组方法 (Common properties and methods of array in JavaScript ) Properties/MethodsDescriptionsarray.lengthReturns the length of the array/total number of elements of the array array[index]Returns the item name stored at “index” pos…

php dbutils 使用,dbutilsapi

相对lisp?而?言,可以使?用.net的强?大api,实现各种酷炫功能。相对c#及arx?...文件utils.py的模块名分别是mycompany.utils和 mycompany.web.utils。 mycompany......CouchDB -b 关闭后台运行的 CouchDB : CouchDB -d web 访问:http://127.0.0.1:5984/_utils/index.html E-…