在.Net中实现RichClient+Restful+JPA架构-探索实现
2012-03-01 20:17
405 查看
兵马未动,粮草先行,开始项目的时候我习惯为项目起一个漂亮的名字,好的开始是成功的一半嘛,一个帅的名字能让我做的更有激情。
呵呵,废话少说,我给项目起的名字是:ElegantSharp,Elegant:优雅的,Sharp:尖锐、锋利。
好的架构注定是优雅的,漂亮的;而且必定是尖锐锋利的。
一、技术选型
我们要实现的架构是RichClient(富客户端)+Restful(SOA)+JPA(持久化机制),本架构也是目前系统架构的主流趋势。
1、首先分析富客户端技术,UI作为直接接触用户的层面,交互性、稳定性、速度、美观、便捷、友好是主要的研究方向,目前市面上比较流行的RichCilent技术主要有:JQuery,Ext.Net(Extjs),Dojo。
JQuery:轻量、开源、资源繁多、也是最受欢迎的富客户端技术,但相对来说控件库不足,仍需要用户自己扩展实现。
Ext.net:不支持MVC3.0的Razor模式,直接放弃,另一个基于Ext.net的框架以前已经实现过,并且做了很多的企业应用系统,总体来说Ext.net能大大提高开发效率,而且有丰富的控件库,但ADSL外网网络基本上会卡死,另外如果页面控件多了,浏览器占用内存相当严重,比较适合做企业内部不太复杂的应用(想学习的朋友可以看:/article/4980445.html)。
Extjs:收费,学习代价相对较高,暂不考虑
Dojo:学习成本较高,而且以前从未搞过
那么我们初步选型采用JQuery UI来实现UI层。
2、Restful(服务层)
据我所知,在C#里面实现Restful,貌似WCF Rest提供一套机制,看过一套源码。另外据说MVC也支持Restful,但目前还没发现应该怎么用,这一块的技术先暂时放一下,还需要慢慢研究下,如果有熟悉的朋友,请您留言,学习一下。
3、JPA(JAVA里的概念),持久化机制,目前比较火的主要有DBUtility,NHibernate,EF4.x(EF5.x)。
以前的开发一直用的是自己封装好的一套ORM,问题虽然没发现,但总感觉不靠谱,这次既然要做一套比较主流的架构,那么也应该配用潮流的东西。Nhibernate以前一用过,但总感觉要配置太多的东西,尤其是引入Spring.Net,只是配置文件就要好多。理所当然我选择了EF4.x配合Linq确实挺爽的,而且EF5马上要到来,据说性能大大的提高了。
4、Of Course 整体UI架构风格采用非常爽的MVC3.0 Razor模式。
二、搭建ElegantDAL层(数据访问层)
要实现的工作:
1、查询所有(FindALL)、分页查询(FindByPage)、获取行数(GetTotalCount)、根据条件获取记录(FindByConditions)、获取单个实体(FindById)、Insert、Update、Delete
2、采用泛型,将这些方法应用到所有的Model
3、配置EF
(1)首先创建数据表:
(2)新建MVC3.0网站,同时创建三个个类库,一个是ElegantModel,一个是ElegantDAL,一个是ElegantBLL
(3) 创建两个表的Model
(3)在ElegantDAL层中,通过NuGet获取最新的EF包,然后创建一个基类:RepositoryBase.cs
因为基类里面配置了连接串,所以请在Web.config中加入相应的配置。
创建上述方法的接口和实现类,这里用到了泛型和Linq的知识,不懂的可以留言询问。
[b]三、数据访问层大功告成了,接下来实现BLL层,BLL就相对简单了,主要用到一个工厂模式。[/b]
BLL我就暂时不写接口了
工厂
四、在UI层里面实现测试,这里只做测试,具体JQuery怎么交互,后面的文章介绍。
我们在HomeController里面写入如下代码:
运行结果如下:
![](http://pic002.cnblogs.com/images/2012/159380/2012030120094510.jpg)
好了,到这里,可以说我们架构搭建只完成了30%,为什么这么说,因为聪明的你会发觉,通篇其实只是做了EF的配置和泛化方法,那么在后面的文章中将会继续探索UI层的JQuery框架实现和Restful的实现,同时希望大牛们能够提供技术支持,技术思路。欢迎留言评论。
呵呵,废话少说,我给项目起的名字是:ElegantSharp,Elegant:优雅的,Sharp:尖锐、锋利。
好的架构注定是优雅的,漂亮的;而且必定是尖锐锋利的。
一、技术选型
我们要实现的架构是RichClient(富客户端)+Restful(SOA)+JPA(持久化机制),本架构也是目前系统架构的主流趋势。
1、首先分析富客户端技术,UI作为直接接触用户的层面,交互性、稳定性、速度、美观、便捷、友好是主要的研究方向,目前市面上比较流行的RichCilent技术主要有:JQuery,Ext.Net(Extjs),Dojo。
JQuery:轻量、开源、资源繁多、也是最受欢迎的富客户端技术,但相对来说控件库不足,仍需要用户自己扩展实现。
Ext.net:不支持MVC3.0的Razor模式,直接放弃,另一个基于Ext.net的框架以前已经实现过,并且做了很多的企业应用系统,总体来说Ext.net能大大提高开发效率,而且有丰富的控件库,但ADSL外网网络基本上会卡死,另外如果页面控件多了,浏览器占用内存相当严重,比较适合做企业内部不太复杂的应用(想学习的朋友可以看:/article/4980445.html)。
Extjs:收费,学习代价相对较高,暂不考虑
Dojo:学习成本较高,而且以前从未搞过
那么我们初步选型采用JQuery UI来实现UI层。
2、Restful(服务层)
据我所知,在C#里面实现Restful,貌似WCF Rest提供一套机制,看过一套源码。另外据说MVC也支持Restful,但目前还没发现应该怎么用,这一块的技术先暂时放一下,还需要慢慢研究下,如果有熟悉的朋友,请您留言,学习一下。
3、JPA(JAVA里的概念),持久化机制,目前比较火的主要有DBUtility,NHibernate,EF4.x(EF5.x)。
以前的开发一直用的是自己封装好的一套ORM,问题虽然没发现,但总感觉不靠谱,这次既然要做一套比较主流的架构,那么也应该配用潮流的东西。Nhibernate以前一用过,但总感觉要配置太多的东西,尤其是引入Spring.Net,只是配置文件就要好多。理所当然我选择了EF4.x配合Linq确实挺爽的,而且EF5马上要到来,据说性能大大的提高了。
4、Of Course 整体UI架构风格采用非常爽的MVC3.0 Razor模式。
二、搭建ElegantDAL层(数据访问层)
要实现的工作:
1、查询所有(FindALL)、分页查询(FindByPage)、获取行数(GetTotalCount)、根据条件获取记录(FindByConditions)、获取单个实体(FindById)、Insert、Update、Delete
2、采用泛型,将这些方法应用到所有的Model
3、配置EF
(1)首先创建数据表:
CREATE TABLE [dbo].[WMS_USERFUN]( [funid] [int] primary key, [funno] [varchar](200) NOT NULL, [funname] [varchar](100) NOT NULL, [fatherid] [int] NULL ) CREATE TABLE [dbo].[WMS_ROLEFUN]( [pid] [int] IDENTITY(1,1) primary key, [roleid] [int] NOT NULL, [funid] [int] NOT NULL )
(2)新建MVC3.0网站,同时创建三个个类库,一个是ElegantModel,一个是ElegantDAL,一个是ElegantBLL
(3) 创建两个表的Model
Model接口文件IEntity
namespace ElegantModel { public interface IEntity { int Id { get; } } }
using System; using System.Collections; using System.ComponentModel; using System.ComponentModel.DataAnnotations; /** * 作者:陈杰 * QQ : 710782046 * Email:ovenjackchain@gmail.com * Web :http://www.ChinaCloudTech.com */ namespace ElegantModel { public class WMS_USERFUN : IEntity { public WMS_USERFUN() { } #region 属性 /// <summary> /// 节点ID /// </summary> /// //指定该为主键 [Key,Column("funid")] [DatabaseGenerated(DatabaseGeneratedOption.None)] public int Id { get; set; } /// <summary> /// 功能链接 /// </summary> public string funno { get; set; } /// <summary> /// 功能名称 /// </summary> public string funname { get; set; } /// <summary> /// 父节点 /// </summary> public int fatherid { get; set; } #endregion } } using System; using System.Collections; using System.ComponentModel; using System.ComponentModel.DataAnnotations; /** * 作者:陈杰 * QQ : 710782046 * Email:ovenjackchain@gmail.com * Web :http://www.chinacloudtech.com */ namespace ElegantModel { public class WMS_ROLEFUN:IEntity { #region 构造函数 public WMS_ROLEFUN() { } #endregion #region 属性 [Key,Column("pid")] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } public int roleid { get; set; } public int funid { get; set; } #endregion } }
(3)在ElegantDAL层中,通过NuGet获取最新的EF包,然后创建一个基类:RepositoryBase.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data.Entity; using ElegantModel; namespace ElegantDAL { public class DB : DbContext { //配置连接串 public DB() : base("DBConStr") { } public DbSet<WMS_USERFUN> WMS_USERFUN { get; set; } public DbSet<WMS_ROLEFUN> WMS_ROLEFUN { get; set; } } public abstract class RepositoryBase { #region 单件模式创建一个类对象 private static DB dbContext = null; protected static DB CreateInstance() { if (dbContext == null) dbContext = new DB(); return dbContext; } #endregion public DB _db = CreateInstance(); } }
因为基类里面配置了连接串,所以请在Web.config中加入相应的配置。
<configuration> <connectionStrings> <add name="DBConStr" connectionString="Data Source=localhost;User ID=sa;Password=ovenjackchain;DataBase=WebMisSharp;" providerName="System.Data.SqlClient" /> </connectionStrings> .....
创建上述方法的接口和实现类,这里用到了泛型和Linq的知识,不懂的可以留言询问。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Linq.Expressions; namespace ElegantDAL { public interface IEFRepository<T> where T:class { List<T> FindAll(); List<T> FindByConditions(Func<IQueryable<T>, IOrderedQueryable<T>> order, params Expression<Func<T, bool>>[] filters); List<T> FindByPage(int startIndex, int pageSize, Func<IQueryable<T>, IOrderedQueryable<T>> order, Expression<Func<T, bool>> filters); int GetCount(Expression<Func<T, bool>> filters); T FindById(int Id); bool Insert(T _t); bool Update(T _t); bool Delete(T _t); } } using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data.Entity; using ElegantModel; using System.Data; using System.Linq.Expressions; namespace ElegantDAL { public class EFRepository<T> : RepositoryBase, IEFRepository<T> where T : class,IEntity { /// <summary> /// 获取所有的数据 /// </summary> /// <returns></returns> public List<T> FindAll() { return DBSET.ToList(); } /// <summary> /// 根据查询条件和排序方法返回结果集 /// </summary> /// <param name="order">排序方法的委托</param> /// <param name="filters">查询条件</param> public List<T> FindByConditions(Func<IQueryable<T>, IOrderedQueryable<T>> order, params Expression<Func<T, bool>>[] filters) { try { IQueryable<T> rs = DBSET.AsQueryable(); if (filters != null) { foreach (var filter in filters) { if (filter != null) { rs = rs.Where(filter); } } } if (order != null) { rs = order(rs); } return rs.ToList(); } catch { throw; } } /// <summary> /// 根据开始索引、每页大小查询条件和排序方法返回分页结果集,适用于前台分页件 /// </summary> /// <param name="startIndex">开始索引</param> /// <param name="pageSize">页面大小</param> /// <param name="totalCount">数据总数</param> /// <param name="order">排序方法的委托</param> /// <param name="filters">查询条件</param> public List<T> FindByPage(int startIndex, int pageSize,Func<IQueryable<T>, IOrderedQueryable<T>> order, Expression<Func<T, bool>> filters) { try { IQueryable<T> rs = order(DBSET.Where(filters)); if (startIndex < 0 || pageSize < 1) { return rs.ToList(); } else { return rs.Skip(startIndex * pageSize).Take(pageSize).ToList(); } } catch { throw; } } /// <summary> /// 根据条件获取总数据行数 /// </summary> /// <param name="conditions"></param> /// <returns></returns> public int GetCount(Expression<Func<T, bool>> filters) { return DBSET.Count(filters); } /// <summary> /// 根据ID获取实体 /// </summary> /// <param name="Id">实体主键ID</param> /// <returns>返回实体</returns> public T FindById(int Id) { return DBSET.Single(t => t.Id == Id); } /// <summary> /// 插入 /// </summary> /// <param name="_t">实体</param> /// <returns>是否成功</returns> public bool Insert(T _t) { try { DBSET.Add(_t); _db.SaveChanges(); return true; } catch { return false; } } /// <summary> /// 更新 /// </summary> /// <param name="_t">实体</param> /// <returns>是否成功</returns> public bool Update(T _t) { try { var entry = _db.Entry(_t); if (entry.State == EntityState.Detached) { entry.State = EntityState.Modified; } _db.SaveChanges(); return true; } catch { return false; } } /// <summary> /// 删除 /// </summary> /// <param name="_t">实体</param> /// <returns>是否成功</returns> public bool Delete(T _t) { try { DBSET.Remove(_t); _db.SaveChanges(); return true; } catch { return false; } } /// <summary> /// 泛型数据表属性 /// </summary> protected DbSet<T> DBSET { get { return _db.Set<T>(); } } /// <summary> /// 操作提交 /// </summary> //public override void SaveChanges() //{ // base.SaveChanges(); //} } }
[b]三、数据访问层大功告成了,接下来实现BLL层,BLL就相对简单了,主要用到一个工厂模式。[/b]
BLL我就暂时不写接口了
using System; using System.Collections.Generic; using System.Linq; using System.Text; using ElegantDAL; using ElegantModel; using System.Linq.Expressions; namespace ElegantBLL { public class WMS_Core<T> where T : class,IEntity { IEFRepository<T> IEF = new EFRepository<T>(); public List<T> FindAll() { return IEF.FindAll(); } public List<T> FindByConditions(Func<IQueryable<T>, IOrderedQueryable<T>> order, params Expression<Func<T, bool>>[] filters) { return IEF.FindByConditions(order, filters); } public List<T> FindByPage(int startIndex, int pageSize, Func<IQueryable<T>, IOrderedQueryable<T>> order, Expression<Func<T, bool>> filters) { return IEF.FindByPage(startIndex, pageSize, order, filters); } public int GetCount(Expression<Func<T, bool>> filters) { return IEF.GetCount(filters); } public T FindById(int Id) { return IEF.FindById(Id); } public bool Insert(T _t) { return IEF.Insert(_t); } public bool Update(T _t) { return IEF.Update(_t); } public bool Delete(T _t) { return IEF.Delete(_t); } } }
工厂
using System; using System.Collections.Generic; using System.Linq; using System.Text; using ElegantModel; namespace ElegantBLL { public class WMS_Factory { public static WMS_Core<WMS_USERFUN> WMS_USERFUN { get { return new WMS_Core<WMS_USERFUN>(); } } public static WMS_Core<WMS_ROLEFUN> WMS_ROLEFUN { get { return new WMS_Core<WMS_ROLEFUN>(); } } } }
四、在UI层里面实现测试,这里只做测试,具体JQuery怎么交互,后面的文章介绍。
我们在HomeController里面写入如下代码:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using ElegantBLL; using ElegantModel; namespace ElegantSharp.Controllers { public class HomeController : Controller { public ActionResult Index() { ViewBag.Message = "欢迎使用 ASP.NET MVC!"; ViewBag.Count = WMS_Factory.WMS_USERFUN.GetCount(c => true); ViewBag.SingleEntity = WMS_Factory.WMS_USERFUN.FindById(1230); ViewBag.FirstPage = WMS_Factory.WMS_USERFUN.FindByPage(1, 3, rs => rs.OrderByDescending(c => c.Id), c => true); ViewBag.FirstPageCon = WMS_Factory.WMS_USERFUN.FindByPage(0, 3, rs => rs.OrderByDescending(c => c.Id), c => c.fatherid != 0 && c.fatherid != 2000); /* WMS_USERFUN w = new WMS_USERFUN(); w.fatherid = 0; w.funname = "测试xxxx"; w.funno = "abc"; w.Id = 3000; //测试插入 WMS_Factory.WMS_USERFUN.Insert(w); //测试更新 WMS_Factory.WMS_USERFUN.Update(w); WMS_ROLEFUN rolefun = WMS_Factory.WMS_ROLEFUN.FindById(25); //测试删除 if (rolefun != null) WMS_Factory.WMS_ROLEFUN.Delete(rolefun); */ return View(WMS_Factory.WMS_USERFUN.FindAll()); } public ActionResult About() { return View(); } } }
运行结果如下:
![](http://pic002.cnblogs.com/images/2012/159380/2012030120094510.jpg)
好了,到这里,可以说我们架构搭建只完成了30%,为什么这么说,因为聪明的你会发觉,通篇其实只是做了EF的配置和泛化方法,那么在后面的文章中将会继续探索UI层的JQuery框架实现和Restful的实现,同时希望大牛们能够提供技术支持,技术思路。欢迎留言评论。
相关文章推荐
- 在.Net中实现RichClient+Restful+JPA架构-探索实现
- 基于.NET平台的分层架构实战(七)——数据访问层的第一种实现:Access+SQL
- 基于.NET平台的分层架构实战(十)——业务逻辑层的实现
- 基于.NET平台的分层架构实战(十一)——表示层的实现
- 基于.NET平台的分层架构实战(十)——业务逻辑层的实现
- [原创].NET 分布式架构开发实战之四 构建从理想和实现之间的桥梁(前篇)
- 基于.NET平台的分层架构实战(七)—数据访问层的第一种实现:Access+SQL
- .NET中应用程序内共享UdpClient联机的实现方法
- 基于.NET平台的分层架构实战(七)——数据访问层的第一种实现:Access+SQL
- 使用WCF实现SOA面向服务编程“.NET研究”—— 架构设计
- 基于.NET平台的分层架构实战(十)——业务逻辑层的实现
- Yii2 基于RESTful架构的 advanced版API接口开发 配置、实现、测试 (转)
- 基于.NET平台的分层架构实战(十)——业务逻辑层的实现
- 基于.NET平台的分层架构实战(七)——数据访问层的第一种实现:Access+SQL
- 基于.NET平台的分层架构实战(十)——业务逻辑层的实现
- 基于.NET平台的分层架构实战(五)——接口的设计与实现
- WeText项目:一个基于.NET实现的DDD、CQRS与微服务架构的演示案例
- WeText项目:一个基于.NET实现的DDD、CQRS与微服务架构的演示案例
- 基于.NET平台的分层架构实战(四)——实体类的设计与实现
- .net中实现简单三层架构