电商系统架构总结1(EF)
最近主导了一个电商系统的设计开发过程,包括前期分析设计,框架搭建,功能模块的具体开发(主要负责在线支付部分),成功上线后的部署维护,运维策略等等全过程。
虽然这个系统不是什么超大型的电商系统 数亿计的并发,但团队里的主要成员都有多年的开发经验以及电商的经验,系统设计方面还是麻雀虽小,但五脏俱全。
系统客户端有 ios , android,H5,微信小程序,后台方面用.net web api + sql server,图片资源的读写使用阿里云,缓存则自己搭建redis,支付方面既有使用一些第三方支付平台,也有和支付宝微信等。。。。 技术点很多,说实话,基本上一般应用系统开发用到的技术基本都用到了,也遇到了很多的坑。所以觉得把里面的代码整理归纳出来很有必要,对于以后的系统开发,特别同类项目的开发,很有借鉴意义。由于我没有参与前端的开发,所以这里主要以.nt 后台架构的讲述为主。
由于是.nt mvc web api,所以选择了 EF作为orm组件。程序分层架构分为: 数据层 DAL和 IDAL,业务层BLL和IBLL,Entity(实体定义),WebAPI,另外还建了一个Utility项目,用于容纳一些与业务无关并且可以复用的功能性代码以及第三方开源代码,另外还有两个单独的解决方案,一个名为thirdparty的web api项目, 用于和第三方平台的接口交互,包括向短信平台发送短信验证码,向阿里云上传图片,查询 快递单物流状态,向推送平台(极光,微信公众号)推送消息。另一个为windows服务程序,用于执行自动化工作任务。
下面分别讲述。
一、DAL。主要负责封装对EF的底层数据操作。其中有一段对EF 的DBContext 实现单例模式的代码,是我当时从网上摘抄下来的,代码如下
public class DbContextFactory
{
public static WinLinkContext Create()
{
WinLinkContext dbContext = CallContext.GetData("DbContext") as WinLinkContext;
if (dbContext == null)
{
dbContext = new WinLinkContext();
CallContext.SetData("DbContext", dbContext);
}
return dbContext;
}
}
其实我最初使用EF时,我记得官方文档都是提倡 dbcontext 是即用即销的,形如 (using WinLinkContext = new WinLinkContext() ){...} 那样,有必要把dbcontext只实例化一个并缓存下来,这样能提高性能和节省资源吗? 开始由于项目工期紧张,没有考虑太多,想着这是别人使用过的成熟代码,还是某大咖的博文例子,应该错不了。结果后来还是出现了问题。某同事a写日志处理模块的时候,也调用了这个 DbContextFactory.Create() ,本意是想把异常发生时的信息记录到数据库,但由于和业务代码公用一个dbcontext,问题就来了。比如某同事b写了几行 add/update EF的代码,接着又写了几行其他的代码, 还没执行 savechanges,但这几行其他代码出现bug,引发异常,于是日志捕捉到了,日志模块就进行使用ef进行插入日志信息,执行savechanges,这时重点来了 , 这个savechanges就会把整个dbcontext的更新内容提交到数据库了!于是连日志模块都报错了,而且错误提示是同事b的代码内容。当然也有读者会说日志模块应该独立开不应该和业务混在一起,确实后来我们也把它独立开了。但这个例子表明 dbcontext使用单例模式有很大问题,我认为还是应该遵循微软官方示例,即用即销,就算要缓存,至少每个模块独立开,不能整个应用使用唯一的一个。比如把上面的代码稍加变化,根据名称读写不同的dbcontext。
public class DbContextFactory
{
public static WinLinkContext Create(string dbName)
{
WinLinkContext dbContext = CallContext.GetData(dbName) as WinLinkContext;
if (dbContext == null)
{
dbContext = new WinLinkContext();
CallContext.SetData(dbName, dbContext);
}
return dbContext;
}
}
另外还有一个BaseDAL的类,用于封装常规的增删改查以及分页等方法,代码大致如下(里面的db对象就是上文提到dbcontext):
public T Add(T t)
{
return db.Set<T>().Add(t);
} public void Update(T t)
{
db.Set<T>().AddOrUpdate(t);
} public void Delete(T t)
{
db.Set<T>().Remove(t);
}
public bool Delete(string id)
{
var entity = db.Set<T>().Find(id);
if (entity == null)
{
return false;
}
db.Set<T>().Remove(entity);
return true;
} public int Delete(string[] ids)
{
foreach (var item in ids)
{
var entity = db.Set<T>().Find(item);//如果实体已经在内存中,那么就直接从内存拿,如果内存中跟踪实体没有,那么才查询数据库。
db.Set<T>().Remove(entity);
}
return ids.Count();
} public T Find(Expression<Func<T, bool>> findLambda)
{
return db.Set<T>().FirstOrDefault(findLambda);
} public T Find(string id)
{
return db.Set<T>().Find(id);
} public IQueryable<T> Where(Expression<Func<T, bool>> whereLambda)
{
return db.Set<T>().Where(whereLambda);
} public IQueryable<T> GetByPage<Type>(int pageSize, int pageIndex, out int total, Expression<Func<T, bool>> whereLambda, Expression<Func<T, Type>> orderByLambda, bool isAsc)
{
var queryData = db.Set<T>().Where(whereLambda); //是否升序
if (isAsc)
{
queryData = queryData.OrderBy(orderByLambda);
}
else
{
queryData = queryData.OrderByDescending(orderByLambda);
} total = queryData.Count();
if (total > )
{
if (pageIndex <= )
{
queryData = queryData.Take(pageSize);
}
else
{
queryData = queryData.Skip((pageIndex - ) * pageSize).Take(pageSize);
} } return queryData;
}
电商系统架构总结1(EF)的更多相关文章
- 电商系统架构总结2(Redis)
二 Redis缓存 考虑到将来服务器的升级扩展,使用redis代替.net内置缓存是比较理想的选择.redis是非常成熟好用的缓存系统,安装配置非常简单,直接上官网下载安装包 安装启动就行了. 1 ...
- 电商系统架构总结4(webapi 版本控制)
为了 顺利迭代升级,web api 在维护过程是不断升级的,但用户是不能强迫他们每次都跟随你去升级,这样会让用户不胜其烦.为了保证不同版本的客户端能同时兼容,在web api接口上加入版本控制就很有必 ...
- 电商系统架构总结3(webapi授权机制)
三 Web API 授权方式 web api的客户端,包括 android,ios,h5,自然对访问权限要加上授权机制.对于h5,要求把h5站点和web api部署在同一个域名下,然后对web api ...
- 集DDD,TDD,SOLID,MVVM,DI,EF,Angularjs等于一身的.NET(C#)开源可扩展电商系统–Virto Commerce
今天一大早来看到园友分享的福利<分享一个前后端分离方案源码-前端angularjs+requirejs+dhtmlx 后端asp.net webapi>,我也来分享一个吧.以下内容由笔者写 ...
- 电商系统的演变可以看出架构演变 Dubbo入门 远程过程调用 需要解决的问题
Dubbo入门---搭建一个最简单的Demo框架 - CSDN博客 https://blog.csdn.net/noaman_wgs/article/details/70214612 Dubbo背景和 ...
- 属性 每秒10万吞吐 并发 架构 设计 58最核心的帖子中心服务IMC 类目服务 入口层是Java研发的,聚合层与检索层都是C语言研发的 电商系统里的SKU扩展服务
小结: 1. 海量异构数据的存储问题 如何将不同品类,异构的数据统一存储起来呢? (1)全品类通用属性统一存储: (2)单品类特有属性,品类类型与通用属性json来进行存储: 2. 入口层是Java研 ...
- (1)dotnet开源电商系统-brnshop&brnMall 和老外开发的nopCommerce(dotnet两套电商来PK--第一篇)
一直想做电商软件,但是实在不想学PHP了,所以前后关注了这两个开源电商系统.一个是国人出品的,一个据说是俄罗斯人写得(不知道对不对).目前两个开源软件都在学习了解中,以下的博文可能会涉及到这两套系统, ...
- 基于SpringBoot+MyBatis实现一套电商系统
项目介绍 mall项目是一套电商系统,包括前台商城系统及后台管理系统,基于SpringBoot+MyBatis实现. 前台商城系统包含首页门户.商品推荐.商品搜索.商品展示.购物车.订单流程.会员中心 ...
- SpringBoot+Security+MyBatis+ES+MQ+Redis+Docker+Vue的电商系统
今天鹏哥给大家推荐的项目是一套电商系统,包括前台商城系统及后台管理系统,基于SpringBoot+MyBatis实现. 前台商城系统包含首页门户.商品推荐.商品搜索.商品展示.购物车.订单流程.会员中 ...
随机推荐
- 深入详解美团点评CAT跨语言服务监控(一) CAT简介与部署
前言: CAT是一个实时和接近全量的监控系统,它侧重于对Java应用的监控,除了与点评RPC组件融合的很好之外,他将会能与Spring.MyBatis.Dubbo 等框架以及Log4j 等结合,支持P ...
- Spring Boot 历史
2012年10月,Mike Youngstrom在Spring jira中创建了一个功能需求,要求在Spring框架中支持无容器Web应用程序体系结构.他建议通过main方法引导的Spring容器内配 ...
- [转]AJAX 简介
AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术. 您应当具备的基础知识 在继续学习之前,您需要对下面的知识有基本的了解: HTML / XHTML CSS JavaScript ...
- Reshape以及向量机分类学习和等高线绘制代码
首先科普一下python里面对于数组的处理,就是如果获取数组大小,以及数组元素数量,这个概念是不一样的,就是一个size和len处理不用.老规矩,上代码: arr2 = np.array([-19.5 ...
- JFrame添加组件
jframe.add(button) 与 jframe.getContentPane().add(button) 结果是一样的, 都是将组件添加到jframe自带的容器ContentPane中.
- Feign 请求拦截器和日志
Feign 支持请求拦截器,在发送请求前,可以对发送的模板进行操作,例如设置请求头等属性,自定请求拦截器需要实现 feign.RequestInterceptor 接口,该接口的方法 apply 有参 ...
- jquery-ajax实现文件批量下载
直接看代码: <script type="text/javascript"> //全选控制 $(document).ready(function() { $(" ...
- ML: 聚类算法R包 - 模型聚类
模型聚类 mclust::Mclust RWeka::Cobweb mclust::Mclust EM算法也称为期望最大化算法,在是使用该算法聚类时,将数据集看作一个有隐形变量的概率模型,并实现模型最 ...
- MySQL性能管理及架构设计
第1章 实例和故事 1-1 什么决定了电商双11大促的成败 老板可能会说:"是我们的英明决策和运筹帷幄". 运营和产品可能会说:"是由于我们的活动策划和产品设计" ...
- js跨域调用mvc ActionResult扩展
背景 最近2个项目中都用到了js跨域访问的知识,2个项目都需要主站与各个分站之间进行数据交互.状态同步等相关操作.浏览器本身是不允许进行跨域访问,在MVC中我们可以扩展一个方法来实现这个功能.在此大家 ...