目录

储存库模式101

撤消存储库模式

进入:LINQPad.ABP


有没有在生产中发现代码在规模上失败得很惨?当性能问题出现,并且有一个名字叫EntityFramework时,只有一个工具可用解决此问题:LINQPad。

但是,如果您使用的是ASP.NET Boilerplate(ABP)框架,那么情况就更糟了。这是因为ABP使用存储库模式,事实证明,该存储库模式与LINQPad的DataContext中心方法不兼容。

在本文中,我将介绍两种将LINQPad与ABP应用程序结合使用来解决性能问题的方法:

  1. 重写基于存储库模式的查询,以在具有数据上下文的LINQPad中运行。这适用于小问题。
  2. 借助LINQPad,我刚刚发布的名为LINQPad.ABP的NuGet Packge可以直接调用您的代码,支持身份验证,多租户以及工作单元和存储库模式。这极大地有助于解决更复杂的性能问题。

储存库模式101

ASP.NET Boilerplate应用程序中使用的“存储库”和“工作单元”模式是一种出色的抽象,可简化单元测试,启用基于注释的事务以及处理数据库连接管理。如Microsoft MVC 文档中的本文所述:

存储库和工作单元模式旨在在应用程序的数据访问层和业务逻辑层之间创建一个抽象层。实施这些模式可以帮助您的应用程序与数据存储中的更改隔离开来,并可以促进自动化的单元测试或测试驱动的开发(TDD)。

该文档提供了一个很好的图表,以显示具有和没有存储库模式的体系结构之间的区别:

但是,这些抽象为LINQPad带来了问题。当使用LINQPad诊断性能问题时,直接调用应用程序的代码以查看将查询转换为SQL并执行查询通常会非常方便。但是,即使LINQPad理解了依赖注入,也不知道如何填充IRepository,如何处理[UnitOfWork(TransactionScopeOption.RequiresNew)]属性或为IAbpSession.UserId或IAbpSession.TenantId返回什么值。幸运的是,我刚刚发布了一个NuGet软件包以使其变得容易。

但是首先,解决单个查询问题的最简单方法就是重写没有存储库模式的查询并将其粘贴到LINQPad中。

撤消存储库模式

第一步是使ABP的数据上下文支持采用连接字符串的构造函数。如果将以下代码添加到你的DataContext中:

#if DEBUGprivate string _connectionString;////// For LINQPad///public MyProjDbContext(string connectionString): base(new DbContextOptions()){_connectionString = connectionString;}protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){if (_connectionString == null){base.OnConfiguring(optionsBuilder); // Normal operationreturn;}// We have a connection stringvar dbContextOptionsBuilder = new DbContextOptionsBuilder();optionsBuilder.UseSqlServer(_connectionString);base.OnConfiguring(dbContextOptionsBuilder);}#endif

然后在LINQPad中,您可以:

  1. 添加连接
  2. “使用您自己的程序集中的类型化数据上下文”
  3. 选择自定义程序集的路径,例如“MyProjSolution\server\src\MyProj.Web.Host\bin\Debug\netcoreapp2.1\MyProj.EntityFrameworkCore.dll
  4. 输入完整DbContext类型名称,如“MyProj.EntityFrameworkCore.MyAppDbContext”
  5. LINQPad应该通过接受字符串的构造函数实例化您的DbContext代码,然后提供您的连接字符串

现在,当您开始一个新查询时,您可以编写:

var thing = this.Things.Where(t => t.Id == 1);
thing.Dump();

而且,如果运行它,您将看到生成的SQL语句。

不错。如果粘贴任何真实代码,则需要添加using语句并替换_thingRepository.GetAll()为this.Things,并且您将立即将LINQ转换为SQL。

它当然适用于简单的查询。

但是,以我的经验,性能问题很少出现在系统的简单部分。性能问题似乎总是发生在多个类相互作用的地方,因为对于作者来说,将所有这些都塞进一个类并能够在晚上入睡根本就没有太多逻辑。

进入:LINQPad.ABP

为了使LINQPad能够直接调用ABP代码,您需要设置依赖项注入,定义一个启动核心模块的模块,指定要模拟的当前用户和租户,并以某种方式覆盖默认的工作单元以使用LINQPad的上下文,而不是ABP的上下文。这是很多工作。

幸运的是,我刚刚发布了LINQPad.ABP,这是一个为您完成所有这些工作的开源NuGet包。要启用它:

  1. 在LINQPad中,添加对“LINQPad.ABP”的引用。
  2. 添加一个依赖于您项目的特定EF模块的自定义模块。
  3. 创建并缓存LINQPad ABP上下文。
  4. 启动UnitOfWork并指定您要模拟的用户和租户。

该代码将如下所示:

// you may need to depend on additional modules here e.g., MyProjApplicationModule
[DependsOn(typeof(MyProjEntityFrameworkModule))]
// this is a lightweight custom module just for LINQPad
public class LinqPadModule : LinqPadModuleBase
{public LinqPadModule(MyProjEntityFrameworkModule abpProjectNameEntityFrameworkModule){// tell your project's EF module to refrain from seeding the DBabpProjectNameEntityFrameworkModule.SkipDbSeed = true;}public override void InitializeServices(ServiceCollection services){// add any custom dependency injection registrations hereIdentityRegistrar.Register(services);}
}async Task Main()
{// LINQPad.ABP caches (expensive) module creation in LINQPad's cachevar abpCtx = Util.Cache(LinqPadAbp.InitModule(), "LinqPadAbp");// specify the tenant or user you want to impersonate hereusing (var uowManager = abpCtx.StartUow(this, tenantId: 5, userId: 8)){// retrieve what you need with IocManager in LINQPad.ABP's contextvar thingService = abpCtx.IocManager.Resolve();var entity = await thingService.GetEntityByIdAsync(1045);entity.Dump();}
}

那可能看起来很多代码,但是请相信我,它比以前要简单得多。现在,您可以调用代码并观看每个查询以及如何将查询转换为SQL。我希望这可用更快的帮助你跟踪到困难的bug。

在LINQPad中征服ASP.NET Boilerplate查询性能相关推荐

  1. ORACLE中Like与Instr模糊查询性能大比拼

    instr(title,'手册')>0  相当于  title like '%手册%' instr(title,'手册')=1  相当于  title like '手册%' instr(titl ...

  2. mysql分页 disti_MySql查询性能优化

    慢查询判定 1.开启慢查询日志记录执行时间超过long_query_time 秒的sql语句 2.通过show processlist命令查看线程执行状态 3.通过explain解析sql了解执行状态 ...

  3. 从ASP.NET Boilerplate v5 +到ABP框架的迁移

    文章目录 介绍 我应该迁移吗? 那ASP.NET Zero呢? ASP.NET MVC 5.x项目 迁移进度 创建解决方案 关于预构建模块 领域层 聚合根和实体 复合主键 聚合根 迁移现有实体 文献资 ...

  4. 搜集《ASP.NET中常用的26个优化性能方法》

    1. 数据库访问性能优化 a.数据库的连接和关闭 访问数据库资源需要创建连接.打开连接和关闭连接几个操作.这些过程需要多次与数据库交换信息以通过身份验证,比较耗费服务器资源.ASP.NET中提供了连接 ...

  5. ASP.NET中常用的26个优化性能方法(转)

    1. 数据库访问性能优化 数据库的连接和关闭 访问数据库资源需要创建连接.打开连接和关闭连接几个操作.这些过程需要多次与数据库交换信息以通过身份验证,比较耗费服务器资源.ASP.NET中提供了连接池( ...

  6. .NET Core 3.0 Preview 6中对ASP.NET Core和Blazor的更新

    我们都知道在6月12日的时候微软发布了.NET Core 3.0的第6个预览版.针对.NET Core 3.0的发布我们国内的微软MVP-汪宇杰还发布的官翻版的博文进行了详细的介绍.具体的可以关注&q ...

  7. ASP.NET中常用的26个优化性能方法

    1. 数据库访问性能优化 数据库的连接和关闭 访问数据库资源需要创建连接.打开连接和关闭连接几个操作.这些过程需要多次与数据库交换信息以通过身份验证,比较耗费服务器资源.ASP.NET中提供了连接池( ...

  8. 更新丨.NET 7 预览版2 中的 ASP.NET Core

    点击上方蓝字  关注我们 (本文阅读时间:6分钟) .NET 7 预览版2 现已推出,其中包括对 ASP.NET Core 的许多重大改进. 以下是此预览版中新增内容的摘要: • 推断来自服务的 AP ...

  9. Asp.Net Boilerplate微服务实战(二)架构解析

    这一章节,我来介绍一下Asp.Net Boilerplate框架在微服务开发中所用到的技术及其大体的组织架构.由于本系列仅讨论ABP框架在微服务架构下的应用方案,不涉及具体的业务逻辑,所以在文中,不讨 ...

最新文章

  1. Codeforces 338D 对线性同余方程组的一点理解
  2. laravel博客中文章删除遇到问题
  3. 怎样将包含元组的列表转换为字典?
  4. [YTU]_2433( C++习题 对象数组求最大值)
  5. 精进:如何成为一个很厉害的人---书摘(转)
  6. java.lang.ClassCastException: cannot assign instance of java.lang.invoke.SerializedLambda to field
  7. SAP Fiori Launchpad Tile点击后跳转的调试技巧
  8. Deployment descriptor
  9. BZOJ 1016: [JSOI2008]最小生成树计数( kruskal + dfs )
  10. 多媒体分析与理解_多媒体在课堂教学中应用的研究研究报告(二)
  11. php 当前时间 当前时间戳和数据库里取出的时间datetime格式进行比较大小
  12. 小甲鱼Python学习笔记之函数(二)
  13. Fineui 添加打印控件
  14. 安卓模拟器安装教程_雷电安卓模拟器v4.0.38绿色免安装版——墨涩网
  15. 基本矩阵F、本质矩阵E、单应矩阵H的关系
  16. android serviceconnection 作用,Android Service服务的相关介绍
  17. 四川地区办理增值电信经营许可证
  18. pa皮安级电流检测电路
  19. 独立窗口打开多个Excel
  20. vue中style scoped属性的作用和原理以及scoped穿透

热门文章

  1. python调用函数怎么错_在Python中从类调用函数时参数数目错误
  2. python中json使用方法总结_python中的json总结
  3. python怎么安装json_python里面怎么安装json包
  4. 东方韵味传统迎接新年|旭日东升的吉利日出好运插画素材模板
  5. 设计灵感素材网站:美工设计者必备
  6. 电商移动促销页面设计素材PSD分层模板,轻松出稿稿
  7. Introduction to PCI Express | PDF
  8. Nginx-1.18.0主函数main思维导图(第一版)
  9. C语言CURL实现HTTP POST、GET、PUT
  10. 5G独立组网与非独立组网