最近主导了一个电商系统的设计开发过程,包括前期分析设计,框架搭建,功能模块的具体开发(主要负责在线支付部分),成功上线后的部署维护,运维策略等等全过程。

虽然这个系统不是什么超大型的电商系统 数亿计的并发,但团队里的主要成员都有多年的开发经验以及电商的经验,系统设计方面还是麻雀虽小,但五脏俱全。

系统客户端有 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)的更多相关文章

  1. 电商系统架构总结2(Redis)

    二  Redis缓存 考虑到将来服务器的升级扩展,使用redis代替.net内置缓存是比较理想的选择.redis是非常成熟好用的缓存系统,安装配置非常简单,直接上官网下载安装包 安装启动就行了. 1 ...

  2. 电商系统架构总结4(webapi 版本控制)

    为了 顺利迭代升级,web api 在维护过程是不断升级的,但用户是不能强迫他们每次都跟随你去升级,这样会让用户不胜其烦.为了保证不同版本的客户端能同时兼容,在web api接口上加入版本控制就很有必 ...

  3. 电商系统架构总结3(webapi授权机制)

    三 Web API 授权方式 web api的客户端,包括 android,ios,h5,自然对访问权限要加上授权机制.对于h5,要求把h5站点和web api部署在同一个域名下,然后对web api ...

  4. 集DDD,TDD,SOLID,MVVM,DI,EF,Angularjs等于一身的.NET(C#)开源可扩展电商系统–Virto Commerce

    今天一大早来看到园友分享的福利<分享一个前后端分离方案源码-前端angularjs+requirejs+dhtmlx 后端asp.net webapi>,我也来分享一个吧.以下内容由笔者写 ...

  5. 电商系统的演变可以看出架构演变 Dubbo入门 远程过程调用 需要解决的问题

    Dubbo入门---搭建一个最简单的Demo框架 - CSDN博客 https://blog.csdn.net/noaman_wgs/article/details/70214612 Dubbo背景和 ...

  6. 属性 每秒10万吞吐 并发 架构 设计 58最核心的帖子中心服务IMC 类目服务 入口层是Java研发的,聚合层与检索层都是C语言研发的 电商系统里的SKU扩展服务

    小结: 1. 海量异构数据的存储问题 如何将不同品类,异构的数据统一存储起来呢? (1)全品类通用属性统一存储: (2)单品类特有属性,品类类型与通用属性json来进行存储: 2. 入口层是Java研 ...

  7. (1)dotnet开源电商系统-brnshop&brnMall 和老外开发的nopCommerce(dotnet两套电商来PK--第一篇)

    一直想做电商软件,但是实在不想学PHP了,所以前后关注了这两个开源电商系统.一个是国人出品的,一个据说是俄罗斯人写得(不知道对不对).目前两个开源软件都在学习了解中,以下的博文可能会涉及到这两套系统, ...

  8. 基于SpringBoot+MyBatis实现一套电商系统

    项目介绍 mall项目是一套电商系统,包括前台商城系统及后台管理系统,基于SpringBoot+MyBatis实现. 前台商城系统包含首页门户.商品推荐.商品搜索.商品展示.购物车.订单流程.会员中心 ...

  9. SpringBoot+Security+MyBatis+ES+MQ+Redis+Docker+Vue的电商系统

    今天鹏哥给大家推荐的项目是一套电商系统,包括前台商城系统及后台管理系统,基于SpringBoot+MyBatis实现. 前台商城系统包含首页门户.商品推荐.商品搜索.商品展示.购物车.订单流程.会员中 ...

随机推荐

  1. 我发起了一个 .Net 开源 数据库 项目 SqlNet

    大家好 , 我发起了一个 .Net 开源 数据库 项目 SqlNet . 项目计划 是 用 C# 写一个 关系数据库 . 可以先参考我之前写的 2 篇文章 : 谈谈数据库原理    https://w ...

  2. Golang 操作mysql使用举例---连接本地数据库

    连接数据库的方式有两种:TCP和Unix域socket. 本文使用Unix domain sockets连接数据库.关于TCP连接数据库可以参考Go 操作mysql使用举例 下面例子中,演示了使用sh ...

  3. ajaxFileupload 多文件上传

    ajaxFileupload 多文件上传 修改前的代码: var oldElement = jQuery('#' + fileElementId); var newElement = jQuery(o ...

  4. kindeditor在线编辑器的使用心得

    1. 如何声明引用? <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> ...

  5. HDFS管理工具HDFS Explorer

    HDFS Explorer是一个在windows上管理HDFS系统的工具,支持上传.下载.重命.复制.移动和删除等. 一.下载地址 CSDN下载地址:http://download.csdn.net/ ...

  6. golang里json的处理配合struct是相当方便

    type Feed struct { Name string `json:"site"` URI string `json:"link"` Type strin ...

  7. 窗体Form的FormStyle属性设置为fsStayOnTop时属性设置不起作用问题探讨。

    procedure CreateParams(var Params: TCreateParams); override; procedure MainForm.Createparams(var Par ...

  8. 为什么.net 4.6.1装了却没看到

    今天在做SignalR网站,需要在发布到的云服务器安装.net4.6.1 从网上下载了安装包,安装完之后,到Windows文件夹的 Microsoft.NET文件夹中却找不到4.6.1的文件夹. 云服 ...

  9. Linux From Scratch [3]

    1. 为了编译glibc,我们需要kernel header. make mrproper # clean kernel tree make INSTALL_HDR_PATH=dest headers ...

  10. 关于Javascript闭包(Closure)

    闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域 ...