[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,一经查实,立即删除!

相关文章

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

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

c++ websocket客户端_websocket使用

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

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

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

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;…

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…

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

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

将搜索二叉树转换为链表_将给定的二叉树转换为双链表(DLL)

将搜索二叉树转换为链表Given a Binary tree and we have to convert it to a Doubly Linked List (DLL). 给定二叉树&#xff0c;我们必须将其转换为双链表(DLL)。 Algorithm: 算法&#xff1a; To solve the problem we can follow this algorithm: 为了解决这个问题&#…

cuda编程_CUDA刷新器:CUDA编程模型

CUDA刷新器&#xff1a;CUDA编程模型 CUDA Refresher: The CUDA Programming Model CUDA&#xff0c;CUDA刷新器&#xff0c;并行编程 这是CUDA更新系列的第四篇文章&#xff0c;它的目标是刷新CUDA中的关键概念、工具和初级或中级开发人员的优化。 CUDA编程模型提供了GPU体系结…

java 逻辑表达式 布尔_使用基本逻辑门实现布尔表达式

java 逻辑表达式 布尔将布尔表达式转换为逻辑电路 (Converting Boolean Expression to Logic Circuit) The simplest way to convert a Boolean expression into a logical circuit is to follow the reverse approach in which we start from the output of the Boolean expre…

python自然语言处理书籍_精通Python自然语言处理pdf

自然语言处理&#xff08;NLP&#xff09;是有关计算语言学与人工智能的研究领域之一。NLP主要关注人机交互&#xff0c;它提供了计算机和人类之间的无缝交互&#xff0c;使得计算机在机器学习的帮助下理解人类语言。 本书详细介绍如何使用Python执行各种自然语言处理&#xff…

通达oa 2013 php解密,通达OA漏洞学习 - 安全先师的个人空间 - OSCHINA - 中文开源技术交流社区...

说明通达OA漏洞在去年上半年已爆出&#xff0c;这不趁着周末没事做&#xff0c;将源码下载下来进行复现学习。文件包含测试文件包含检测&#xff0c;payload1:ip/ispirit/interface/gateway.php?json{"url":"/general/../../mysql5/my.ini"}利用文件包含访…

公众号 -「前端攻略 开光篇」

作为一枚程序员&#xff0c;每件重要项目的开始都忍不住使用"Hello World"。 这个公众号是不是来晚了&#xff1f;如果你有这个疑问&#xff0c;那么我想说&#xff1a;对于写作和思考&#xff0c;任何时候都不晚。我用四个简单的自问自答&#xff0c;来讲讲这个前端…

matlab中求模最大,matlab求取模极大值时出错

本帖最后由 Nate_ 于 2016-4-17 15:57 编辑points1024 时&#xff0c;有波形输出&#xff0c;但信号有5438个点。改为5438就不行。主程序&#xff1a;%小波模极大值重构是采用的交替投影法close all;points5438; level4; sr360; num_inter6; wfdb4;%所处理数据的…

【分享】linux下u盘使用

2019独角兽企业重金招聘Python工程师标准>>> linux下u盘使用 方案一&#xff1a; Linux不像Windows一样&#xff0c;接上新硬件后可以自动识别&#xff0c;在Linux下无法自动识别新硬件的&#xff0c;需要手动去识别。USB移动存储设备通常被识别为sda1&#xff0c;…

swift 3.0 中使用 xib

文章写于2016年9月底&#xff0c;Xcode 8&#xff0c;swift 3.0真是蛋疼&#xff0c;折腾了很长时间&#xff0c;试了网上很多教程&#xff0c;结果又莫名的可以了&#xff01; 1.方法和OC中一样 将一个xib文件和一个ViewController类进行关联的几步操作&#xff1a; command &…

numpy 归一化_NumPy 数据归一化、可视化

仅使用 NumPy&#xff0c;下载数据&#xff0c;归一化&#xff0c;使用 seaborn 展示数据分布。下载数据import numpy as npurl https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.datawid np.genfromtxt(url, delimiter,, dtypefloat, usecols[1])仅提取…

puppeteer api_使用Node.js和puppeteer API从URL创建PDF文件

puppeteer apiWe will continue using Node.js and puppeteer which is a node library. As we saw in our last article, Puppeteer is a Node library developed by Google and provides a high-level API for developers. 我们将继续使用Node.js和puppeteer(这是一个节点库)…

servlet的由来

2019独角兽企业重金招聘Python工程师标准>>> 动静态网页技术 首先说下访问网页的大概过程&#xff1a; 你在浏览器中输入网址&#xff0c;按下enter键&#xff0c;此时浏览器代你做了很多事&#xff0c;简要说为&#xff1a;将你输入的这个网址作为目的地参数&#…

php header 文件大小,php获取远程文件大小及信息的函数(head_php

php获取远程文件大小及信息的函数(header头信息获取)阿里西西Alixixi.com开发团队在做一个客户系统时&#xff0c;需要做远程下载的功能&#xff0c;并实时显示进度条效果。所以&#xff0c;需要预先读取远程文件的大小信息&#xff0c;然后做为实时下载进度条的参数。功能函数…