兵马未动,粮草先行,开始项目的时候我习惯为项目起一个漂亮的名字,好的开始是成功的一半嘛,一个帅的名字能让我做的更有激情。

呵呵,废话少说,我给项目起的名字是: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外网网络基本上会卡死,另外如果页面控件多了,浏览器占用内存相当严重,比较适合做企业内部不太复杂的应用(想学习的朋友可以看:http://www.cnblogs.com/qidian10/archive/2011/01/24/1943489.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();//}    }}

三、数据访问层大功告成了,接下来实现BLL层,BLL就相对简单了,主要用到一个工厂模式。

    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();        }    }}

运行结果如下:

好了,到这里,可以说我们架构搭建只完成了30%,为什么这么说,因为聪明的你会发觉,通篇其实只是做了EF的配置和泛化方法,那么在后面的文章中将会继续探索UI层的JQuery框架实现和Restful的实现,同时希望大牛们能够提供技术支持,技术思路。欢迎留言评论。

  

在.Net中实现RichClient+Restful+JPA架构-探索实现相关推荐

  1. SpringCloud系列二:Restful 基础架构(搭建项目环境、创建 Dept 微服务、客户端调用微服务)...

    声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.概念:Restful 基础架构 2.具体内容 对于 Rest 基础架构实现处理是 SpringCloud 核心所在,其基本操 ...

  2. 老猿学5G扫盲贴:中移动的5G计费架构中Nchf'服务化接口以及CHF中的AGF

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一.关于Nchf' 在中移动企标中出现了在3GPP ...

  3. MySQL-高可用架构探索

    文章目录 生猛干货 官方文档 前置学习 什么是高可用( HA - High Availability ) 实现高可用的几点原则 避免MySQL单点故障的几种方案 使用SUN共享存储 使用DRDB磁盘复 ...

  4. 熊猫TV直播H5播放器架构探索

    本文来自熊猫TV音视频技术专家姜雨晴在LiveVideoStackCon 2017上的分享,并有LiveVideoStack整理成文.当下,打造一款播放器已经有比较好的开源实现,但熊猫TV为什么还要自 ...

  5. 手机淘宝客户端架构探索实践

    宗心:淘宝无线事业部资深开发工程师,手机淘宝iOS架构组开发工程师,2012年底参与开发手机淘宝iOS3.0版本,经历大小几十个版本的变迁,针对手机淘宝总体设计架构,hybrid框架解决方案,插件化解 ...

  6. CHINC 2022|熙牛医疗CEO墙辉演讲实录-医疗行业双中台架构探索与实践

    墙辉表示:双中台建设的目的,是把医疗机构当作一个不可分割的整体来看,从经营要素.经营过程到经营决策的一体化建模:形成对行业政策和市场环境变化的敏锐洞察:建立以患者为中心的敏捷流程,实现患者服务全过程的 ...

  7. AWS云计算技术架构探索系列之一-开篇

    一.前言 1.什么是AWS AWS是亚马逊公司的云计算 品牌,作为全球云计算技术的首创者和领导者,其分布在全球25区域81个可用区的数据中心,提供200多项服务齐全的云服务(2021年12月份数据), ...

  8. AWS云计算技术架构探索系列之二-身份账户体系(IAM)

    一.前言 建立身份账户体系是我们上云的第一步,良好的账户体系设计,会为后续的管理带来极大的便捷性和扩展性,反之,则可能增加管理的复杂,以及账户使用的不安全. AWS设计了一套完备的身份账号体系,主要包 ...

  9. 声网下一代视频引擎架构探索与实践

    为应对愈发多样化的音视频互动场景下的挑战,Agora 开始设计自己的下一代视频处理引擎,在过程中关于引擎架构.性能调优.插件系统设计等方面总结了很多经验,希望与各位音视频领域的爱好者.行业从业者分享. ...

  10. AWS云计算技术架构探索系列之五-网络

    一.前言 当我们有了计算和存储资源,但是要真正把应用程序运行起来并提供互联网服务,那还需要使用AWS的网络,本章节就一起了解AWS的网络及其相关的组件基础知识和架构,其中包括: 区域(Region), ...

最新文章

  1. 2019年上半年国内学者在植物领域共发表6篇Science, 1篇Nature,1篇Cell!
  2. CentOS7 Apache调优之开启deflate压缩模块
  3. 为啥看恐怖片老是忘不掉?最新研究:恐惧记忆的形成方式更利于稳定存储
  4. datasnap的线程池
  5. python中的一些算法
  6. 提高雅思听力速度必须反复练耳朵别无捷径
  7. gblfy博客配色模板
  8. windows传文件到linux服务器--- secureCRT PK xftp
  9. dxf转g代码_恶意代码分析系列几种常用技术(2)
  10. Python获取每个用户使用的CPU和内存百分比
  11. [Flink]Flink常用的DataStream转换算子
  12. 蓝宝石rx470d原版bios_AMD RX470/570强刷RX580完整图文教程(附文件下载及查BIOS攻略)...
  13. 依赖hutool压缩文件
  14. 爱立信、意大利电信及高通公司基于5G毫米波创下远程传输速度纪录
  15. get_sequencer的用法总结
  16. 抽样技术--简单随机抽样
  17. 【嵌入式工程师的30岁总结】 真实
  18. 《JavaWeb视频教程》(p34)
  19. 2017大数据领域十大必读书籍
  20. Webflux异常处理

热门文章

  1. 课时13—横屏竖屏事件
  2. 11月3日 迅雷白金会员vip账号分享 91freevip 23:00更新
  3. window消息机制
  4. serverlet生命周期
  5. 使用 Eclipse 插件部署 Java 应用
  6. 寒假第七周 2.22 --- 2.28
  7. mysql 历史记录查询
  8. Struts2---ActionContext和ServletActionContext小结
  9. java解惑--摘要
  10. LA 4794 - Sharing Chocolate dp