• 系列教程
  • 开发文档
MySQL常见面试题
MySQL常见面试题
.NET/.NET Core面试题
.NET/.NET Core面试题
vs code 编辑器基础使用专题
vs code 编辑器基础使用专题
abp+vue-element-admin搭建个人网站
abp+vue-element-admin搭建个人网站
C# linq如何使用,无法识别方法等问题专场
C# linq如何使用,无法识别方法等问题专场
.NET Core基于abp vnext 开发个人网站【专题】
.NET Core基于abp vnext 开发个人网站【专题】
网站SEO优化专题,让搜索引擎对网站更有亲和力
网站SEO优化专题,让搜索引擎对网站更有亲和力
  • .NET Core appsettings.json 获取数据库连接字符串

    本文主要介绍.NETCore中,通过appsettings.json配置文件获取数据库连接字符串。

  • MySQL ATAN() 函数

    MySQLATAN()函数返回指定数值的反正切值。ATAN()语法这里是MySQLATAN()函数的语法:ATAN(number)ATAN(x,y)参数number必需的。一个用于计算反正切值的数值。x,y必需的。一个用于计算反正切值的两个数值。x和y的符号用于确定结果的象限。返回值MySQLATA

  • Entity Framework Core

  • Proof Key for Code Exchange (PKCE)

  • MySQL AES_DECRYPT() 函数

    MySQLAES_DECRYPT()函数使用AES加密算法解密一个由AES_ENCRYPT()加密后的字符串。AES_DECRYPT()语法这里是MySQLAES_DECRYPT()函数的语法:AES_DECRYPT(crypt_str,key_str)参数crypt_str必需的。一个要加密的字符

  • ABP 源码解析 一. ABP启动

    介绍此系列文章主要是对ABP源码进行解读,初探作者在创造ABP的框架思路,和使用到的设计模式进行。通过解读ABP源码,可以提升ABP使用方式,可以提升编码意识,提高面向对象编程思想。此篇文章主要解读ABP框架的启动过程已经相关类。ABP启动通过测试代码AbpBootstraper_Tester可以一窥ABP启动类的使用方式abp启动测试代码abp启动测试运行结果由测试代码可知,要启动abp框架,主要是使用类AbpBootstrapper,经过如下步骤定义启动模块创建AbpBootstrapper类实例使用启动模块初始化AbpBootstrapper类的实例调用AbpBootstrapper的初始化代码Initialize源码结构图AbpBootstrapperAbpBootstrapperOptions启动过程1.创建启动实例///<summary>///Createsanew<seecref="AbpBootstrapper"/>instance.///创建<seecref="AbpBootstrapper"/>实例///</summary>///<paramname="startupModule">///Startupmoduleoftheapplicationwhichdependsonotherusedmodules.Shouldbederivedfrom<seecref="AbpModule"/>.///应用程序启用的模块///</param>///<paramname="optionsAction">Anactiontosetoptions///启动选项///</param>privateAbpBootstrapper([NotNull]TypestartupModule,[CanBeNull]Action<AbpBootstrapperOptions>optionsAction=null){Check.NotNull(startupModule,nameof(startupModule));varoptions=newAbpBootstrapperOptions();optionsAction?.Invoke(options);//检查启动模块是否继承AbpModuleif(!typeof(AbpModule).GetTypeInfo().IsAssignableFrom(startupModule)){thrownewArgumentException($"{nameof(startupModule)}shouldbederivedfrom{nameof(AbpModule)}.");}//设置启动模块StartupModule=startupModule;//设置Ioc管理器IocManager=options.IocManager;//设置插件来源PlugInSources=options.PlugInSources;_logger=NullLogger.Instance;//根据选项配置是否加载拦截器if(!options.DisableAllInterceptors){AddInterceptorRegistrars();}}///<summary>///Createsanew<seecref="AbpBootstrapper"/>instance.///创建<seecref="AbpBootstrapper"/>实例///</summary>///<typeparamname="TStartupModule">///Startupmoduleoftheapplicationwhichdependsonotherusedmodules.Shouldbederivedfrom<seecref="AbpModule"/>.///启动模块类///</typeparam>///<paramname="optionsAction">Anactiontosetoptions///启动选项///</param>publicstaticAbpBootstrapperCreate<TStartupModule>([CanBeNull]Action<AbpBootstrapperOptions>optionsAction=null)whereTStartupModule:AbpModule{returnnewAbpBootstrapper(typeof(TStartupModule),optionsAction);}///<summary>///Createsanew<seecref="AbpBootstrapper"/>instance.///</summary>///<paramname="startupModule">///Startupmoduleoftheapplicationwhichdependsonotherusedmodules.Shouldbederivedfrom<seecref="AbpModule"/>.///启动模块类的类型///</param>///<paramname="optionsAction">///Anactiontosetoptions///启动选项///</param>publicstaticAbpBootstrapperCreate([NotNull]TypestartupModule,[CanBeNull]Action<AbpBootstrapperOptions>optionsAction=null){returnnewAbpBootstrapper(startupModule,optionsAction);}///<summary>///注册AOP拦截器///</summary>privatevoidAddInterceptorRegistrars(){ValidationInterceptorRegistrar.Initialize(IocManager);AuditingInterceptorRegistrar.Initialize(IocManager);EntityHistoryInterceptorRegistrar.Initialize(IocManager);UnitOfWorkRegistrar.Initialize(IocManager);AuthorizationInterceptorRegistrar.Initialize(IocManager);}通过调用Create<TStartupModule>或者Create创建AbpBootstrapper实例,AbpBootstrapper的构造方法是private,这也意味着,只能通过这两个方式,创建AbpBootstrapper实例。在AbpBootstrapper构造函数中,主要做了一下几件事:检查启动模块是否继承AbpModule设置启动类中的启动模块设置启动类中的Ioc管理器设置插件来源列表启用拦截器(根据选项确定是否启用)2.程序初始化调用AbpBootstrapper的初始化代码Initialize///<summary>///InitializestheABPsystem.///初始化ABP系统///</summary>publicvirtualvoidInitialize(){//解析日志组件,以便记录启动过程ResolveLogger();try{//注册启动类RegisterBootstrapper();//注册ABP组件IocManager.IocContainer.Install(newAbpCoreInstaller());//加载插件IocManager.Resolve<AbpPlugInManager>().PlugInSources.AddRange(PlugInSources);//初始化启动配置IocManager.Resolve<AbpStartupConfiguration>().Initialize();//初始化模块管理器_moduleManager=IocManager.Resolve<AbpModuleManager>();//初始化模块_moduleManager.Initialize(StartupModule);//启动模块_moduleManager.StartModules();}catch(Exceptionex){_logger.Fatal(ex.ToString(),ex);throw;}}///<summary>///解析日志组件///</summary>privatevoidResolveLogger(){if(IocManager.IsRegistered<ILoggerFactory>()){_logger=IocManager.Resolve<ILoggerFactory>().Create(typeof(AbpBootstrapper));}}///<summary>///注册启动类///</summary>privatevoidRegisterBootstrapper(){if(!IocManager.IsRegistered<AbpBootstrapper>()){//注册自身实例到ioc容器IocManager.IocContainer.Register(Component.For<AbpBootstrapper>().Instance(this));}}在初始化方法中,主要进行一下内容从ioc容器中解析日志组件,以便记录启动过程在Ioc容器中注册启动类自身实例注册ABP组件加载插件启动配置初始化初始化模块管理器初始化启动模块启动模块启动模块之后,整个ABP系统就已经启动完毕.设计模式简单工厂设计模式创建AbpBootstrapper使用了简单工厂设计模式,设置构造函数为private,使得外部环境只能使用static方法创建实例。对于AbpBootstrapper而言,该类自身就是一个工厂类,根据具体的方法返回AbpBootstrapper实例。测试代码public>AbpBootstraper_Tester:TestBaseWithLocalIocManager{privatereadonlyAbpBootstrapper_bootstrapper;publicAbpBootstraper_Tester(){_bootstrapper=AbpBootstrapper.Create<MyTestModule>(options=>{options.IocManager=LocalIocManager;});}[Fact(DisplayName="ABP初始化")]publicvoidShould_Initialize_Bootstrapper(){_bootstrapper.Initialize();}[Fact(DisplayName="ABP启动时初始化模块")]publicvoidShould_Call_Module_Events_Once(){_bootstrapper.Initialize();_bootstrapper.Dispose();vartestModule=LocalIocManager.Resolve<MyTestModule>();varotherModule=LocalIocManager.Resolve<MyOtherModule>();varanotherModule=LocalIocManager.Resolve<MyAnotherModule>();testModule.PreInitializeCount.ShouldBe(1);testModule.InitializeCount.ShouldBe(1);testModule.PostInitializeCount.ShouldBe(1);testModule.ShutdownCount.ShouldBe(1);otherModule.PreInitializeCount.ShouldBe(1);otherModule.InitializeCount.ShouldBe(1);otherModule.PostInitializeCount.ShouldBe(1);otherModule.ShutdownCount.ShouldBe(1);otherModule.CallMeOnStartupCount.ShouldBe(1);anotherModule.PreInitializeCount.ShouldBe(1);anotherModule.InitializeCount.ShouldBe(1);anotherModule.PostInitializeCount.ShouldBe(1);anotherModule.ShutdownCount.ShouldBe(1);}publicoverridevoidDispose(){_bootstrapper.Dispose();base.Dispose();}}[DependsOn(typeof(MyOtherModule))][DependsOn(typeof(MyAnotherModule))]public>MyTestModule:MyEventCounterModuleBase{privatereadonlyMyOtherModule_otherModule;publicMyTestModule(MyOtherModuleotherModule){_otherModule=otherModule;}publicoverridevoidPreInitialize(){base.PreInitialize();_otherModule.PreInitializeCount.ShouldBe(1);_otherModule.CallMeOnStartup();}publicoverridevoidInitialize(){base.Initialize();_otherModule.InitializeCount.ShouldBe(1);}publicoverridevoidPostInitialize(){base.PostInitialize();_otherModule.PostInitializeCount.ShouldBe(1);}publicoverridevoidShutdown(){base.Shutdown();_otherModule.ShutdownCount.ShouldBe(0);//Dependedmoduleshouldbeshutdownafterthismodule}}public>MyOtherModule:MyEventCounterModuleBase{publicintCallMeOnStartupCount{get;privateset;}publicvoidCallMeOnStartup(){CallMeOnStartupCount++;}}public>MyAnotherModule:MyEventCounterModuleBase{}publicabstract>MyEventCounterModuleBase:AbpModule{publicintPreInitializeCount{get;privateset;}publicintInitializeCount{get;privateset;}publicintPostInitializeCount{get;privateset;}publicintShutdownCount{get;privateset;}publicoverridevoidPreInitialize(){IocManager.ShouldNotBe(null);Configuration.ShouldNotBe(null);PreInitializeCount++;}publicoverridevoidInitialize(){InitializeCount++;}publicoverridevoidPostInitialize(){PostInitializeCount++;}publicoverridevoidShutdown(){ShutdownCount++;}}测试运行结果运行结果该测试主要测试ABP是否正常初始化和模块是否正常被调用。我的公众

  • ABP分页实现

    我们在展现层有分页请求时,一般需要指定两个参数,一个用来标志第几页、一个是每页行数(一般有配置文件配置)。因为分页是一个很常用的功能,所以,展现层我们有分页请求时,最好有相应的DTO来封装这两个参数。在ABP源码中并没有为我们封装这样公用的类,但是在ABPZero项目中,定义了相应的分页Dto。对应的类图如下:分页排序过滤相应Dto类图从中可以看到主要包括以下四个公共DTO定义:PagedInputDto:分页请求DtoPagedAndSortedInputDto:分页排序DtoPagedSortedAndFilteredInputDto:分页排序过滤DtoPagedAndFilteredInputDto:分页过滤Dto是不是很实用,我们的分页一般是和过滤排序混合使用的。其中主要定义了以下几个主要属性:MaxResultCount:每页行数,可以从定义的配置中读取。SkipCount:跳转数量,一般计算公式为SkipCount=Page*MaxResultCount(页数*行数)。Filter:过滤字符串Sorting:排序方式具体的实现就不详述了,相信仔细看类图,就能自己动手实现。AbpZero把这些公共Dto定义在了应用服务层的Dto文件夹下,具体路径如下图。2.如何使用分页DTO拿我们的任务清单举例,我们修改下创建的GetTaskInputDto,让它继承自PagedSortedAndFilteredInputDto,这样GetTaskInputDto就拥有了进行分页排序过滤需要用到的属性。public>GetTasksInput:PagedSortedAndFilteredInputDto{publicTaskState?State{get;set;}publicint?AssignedPersonId{get;set;}}3.返回分页结果DTOAbp已经为我们定义了泛型的PagedResultDto用来包装返回的分页结果。其中主要包括两个属性,intTotalCount保存总个数,IReadOnlyList<T>Items保存返回的分页结果集。4.应用服务层分页逻辑实现1、在ITaskAppService中定义接口PagedResultDto<TaskDto>GetPagedTasks(GetTasksInputinput);2、在TaskAppService中实现接口:publicPagedResultDto<TaskDto>GetPagedTasks(GetTasksInputinput){//初步过滤varquery=_taskRepository.GetAll().Include(t=>t.AssignedPerson).WhereIf(input.State.HasValue,t=>t.State==input.State.Value).WhereIf(!input.Filter.IsNullOrEmpty(),t=>t.Title.Contains(input.Filter)).WhereIf(input.AssignedPersonId.HasValue,t=>t.AssignedPersonId==input.AssignedPersonId.Value);//排序query=!string.IsNullOrEmpty(input.Sorting)?query.OrderBy(input.Sorting):query.OrderByDescending(t=>t.CreationTime);//获取总数vartasksCount=query.Count();//默认的分页方式//vartaskList=query.Skip(input.SkipCount).Take(input.MaxResultCount).ToList();//ABP提供了扩展方法PageBy分页方式vartaskList=query.PageBy(input).ToList();returnnewPagedResultDto<TaskDto>(tasksCount,taskList.MapTo<List<TaskDto>>());}分页的实现很简单,先进行过滤,排序,再进行分页,最后使用PagedResultDto封装分页结果。细心的你也许发现了两个未曾在Linq中用过的方法WhereIf和PageBy,是的,这是ABP提供的扩展方法,感兴趣的可以看下源码QueryableExtensions的具体实现,其实实现的很简单,但我们平时在使用linq时却未必能想得到。在这里提几个问题:请问在这段代码中共进行了几次查询?代码中使用的是什么分页技术?(真分页?假分页?)5.使用X.PagedList进行前端分页在Asp.NetMvc中进行前端分页有一系列开源实现,在我的Demo中使用的是开源的X.PagedList分页。想了解具体源码,请参考X.PagedListGitHub。1、请自行在Web项目中安装X.PagedList.MvcNuget程序包X.PagedList.MvcNuget程序包2、在Controller中使用X.PagedList提供的方法构造分页结果供前端使用因为我们在应用服务层已经手动实现了分页逻辑,所以按照X.PagedList官网示例,我们需要自行构造StaticPagedList作为返回结果。publicActionResultPagedList(int?page){//每页行数varpageSize=5;varpageNumber=page??1;//第几页varfilter=newGetTasksInput{SkipCount=(pageNumber-1)*pageSize,//忽略个数MaxResultCount=pageSize};varresult=_taskAppService.GetPagedTasks(filter);//已经在应用服务层手动完成了分页逻辑,所以需手动构造分页结果varonePageOfTasks=newStaticPagedList<TaskDto>(result.Items,pageNumber,pageSize,result.TotalCount);//将分页结果放入ViewBag供View使用ViewBag.OnePageOfTasks=onePageOfTasks;returnView();}从代码中可以看到我们构造完X.PagedList提供的分页结果后放入了ViewBag中,供视图使用。3、View中添加分页控件PagedList视图的代码如下:@usingX.PagedList.Mvc;@usingAbp.Web.Mvc.Extensions@usingX.PagedList;<link>"~/Content/PagedList.css"rel=">"list-group">@foreach(vartaskinViewBag.OnePageOfTasks){<li>="list-group-item"><div>="btn-grouppull-right"><buttontype="button">="btnbtn-info">Edit</button><buttontype="button">="btnbtn-success">Delete</button></div><div>="media"><a>="media-left">"#">@*<i>="fa@Model.GetTaskLable(task)fa-3x"></i>*@</a><div>="media-body"><h4>="media-heading">@task.Title</h4><span>="text-muted">@task.CreationTime.ToString("yyyy-MM-ddHH:mm:ss")</span></div></div></li>}</ul>@Html.PagedListPager((IPagedList)ViewBag.OnePageOfTasks,page=>Url.Action("PagedList",new{page}))其中最后一句代码是用来生成分页控件。最终效果如图:总结本节主要讲解了如何使用ABP进行后台分页,并顺带讲解了ABP后台分页逻辑的实现方式。同时也演示了如何使用X.PagedList进行前端分页

  • 微信h5支付商家存在未配置的参数xxx

    问题的起因在微信环境下我们的支付流程都可以跑通,一点毛病都没有。但是转到浏览器中就出现问题 “商家存在未配置

CSS|HTML   小程序开发   运维部署  开发技巧 推荐阅读

文章|阅读

  • 系列文章列表,点击展示/隐藏系列教程一目录:知识点源码解析系列教程二目录:BcvpAbpVnext讲解系列教程三目录:单个知识点讲解系列教程四目录:分库分表(日志系统案例讲解)本文梯子正文说明AbpvNext基础篇的文章还差一个单元测试模块就基本上完成了我争取10.1放假之前给大家赶稿出来,后面我们会开始进阶篇,开始拆一些东西,具体要做的事我会单独开一个文章来讲缘起本篇文章缘起于dyAbp大佬们在给夏琳儿(简称:小富婆)讲解技术的时候发起,因为多用户设计和用户扩展属性设计在社区已经是一个每天都会有人来问一遍的问题,这里浅谈一下我的理解,源码是根据EasyAbp作者Super写的代码,根据我自己的理解去分析的想法。扩展属性先从我们单用户系统来讲,如果我该如何扩展用户属性?在Abp默认解决方案Domain.Shared中更改ConpExtraProperties,该操作会向IdentityUser实体添加SocialSecurityNumber属性publicstaticvoidConpExtraProperties(){OneTimeRunner.Run(()=>{ObjectExtensionManager.Instance.Modules().ConpIdentity(identity=>{identity.ConpUser(user=>{user.AddOrUpdateProperty<string>(//propertytype:string"SocialSecurityNumber",//propertynameproperty=>{//validationrulesproperty.Attributes.Add(newRequiredAttribute());property.Attributes.Add(newStringLengthAttribute(64){MinimumLength=4});//...otherconfigurationsforthisproperty});});});});}EntityExtensions还提供了很多配置操作,这里就简单的举几个常用的例子更多详细操作可以在文章下方连接到官方连接。//默认值选项property=>{property.DefaultValue=42;}//默认值工厂选项property=>{property.DefaultValueFactory=()=>DateTime.Now;}//数据注解属性property=>{property.Attributes.Add(newRequiredAttribute());property.Attributes.Add(newStringLengthAttribute(64){MinimumLength=4});}//验证操作property=>{property.Attributes.Add(newRequiredAttribute());property.Attributes.Add(newStringLengthAttribute(64){MinimumLength=4});property.Validators.Add(context=>{if(((string)context.Value).StartsWith("B")){context.ValidationErrors.Add(newValidationResult("Socialsecuritynumbercannotstartwiththeletter'B',sorry!",new[]{"extraProperties.SocialSecurityNumber"}));}});}目前这种配置方式如果你的前端是mvc或者razorpages是不需要改动代码的,页面会动态生成字段,但是如果是angular就需要人工来操作了,除了扩展属性外,你可能还需要部分或完全覆盖某些服务和页面组件才行,不过Abp官方文档都有相应的操作指南所以没有任何问题。具体更多操作官方地址:https://docs.abp.io/en/abp/latest/Module-Entity-Extensions另外就是大家最关系的数据存储问题,默认我们添加的数据都会在ExtraProperties以JSON对象方式进行存储但如果你想用字段的方式进行存储的话,可以在你的.EntityFrameworkCore项目的类中写下这个。然后您需要使用标准Add-Migration和Update-Database命令来创建新的数据库迁移并将更改应用到您的数据库。ObjectExtensionManager.Instance.MapEfCoreProperty<IdentityUser,string>("SocialSecurityNumber",(entityBuilder,propertyBuilder)=>{propertyBuilder.HasMaxLength(64);});多用户设计举例你要开发学生管理系统老师和学生都会进入系统来做自己对应的操作,我们如何来隔离呢?首先我们就可以想到通过角色来做权限分配做能力隔离然后学生和老师的参数不一样,怎么办,老师要填写工号、系部、教学科目、工龄,学生要填写年度、班级、学号?,看到过比较粗暴的方案就是直接在IdentityUser表全给干上去,但是这种做法相对于某个角色来看是不是太冗余?这里我参考Super的一个做法采用使用自己的数据库表/集合创建新实体,具体什么意思呢?我们创建Teacher实体,该实体通过UserId指定IdentityUser,来存储作为老师的额外属性public>Teacher:AggregateRoot<Guid>,IMultiTenant{publicvirtualGuid?TenantId{get;protectedset;}publicvirtualGuidUserId{get;protectedset;}publicvirtualboolActive{get;protectedset;}[NotNull]publicvirtualstringName{get;protectedset;}publicvirtualint?Age{get;protectedset;}protectedTeacher(){}publicTeacher(Guidid,Guid?tenantId,GuiduserId,boolactive,[NotNull]stringname,int?age):base(id){TenantId=tenantId;UserId=userId;Update(active,name,age);}publicvoidUpdate(boolactive,[NotNull]stringname,int?age){Active=active;Name=name;Age=age;}}处理方案是通过订阅UserEto,这是User预定义的专用事件类,当User产生Created、Updated和Deleted操作收会到通知,然后执行我们自己逻辑,[UnitOfWork]public>TeacherUserInfoSynchronizer:IDistributedEventHandler<EntityCreatedEto<UserEto>>,IDistributedEventHandler<EntityUpdatedEto<UserEto>>,IDistributedEventHandler<EntityDeletedEto<UserEto>>,ITransientDependency{privatereadonlyIGuidGenerator_guidGenerator;privatereadonlyICurrentTenant_currentTenant;privatereadonlyIUserRoleFinder_userRoleFinder;privatereadonlyIRepository<Teacher,Guid>_teacherRepository;publicTeacherUserInfoSynchronizer(IGuidGeneratorguidGenerator,ICurrentTenantcurrentTenant,IUserRoleFinderuserRoleFinder,IRepository<Teacher,Guid>teacherRepository){_guidGenerator=guidGenerator;_currentTenant=currentTenant;_userRoleFinder=userRoleFinder;_teacherRepository=teacherRepository;}publicasyncTaskHandleEventAsync(EntityCreatedEto<UserEto>eventData){if(!awaitHasTeacherRoleAsync(eventData.Entity)){return;}awaitCreateOrUpdateTeacherAsync(eventData.Entity,true);}publicasyncTaskHandleEventAsync(EntityUpdatedEto<UserEto>eventData){if(awaitHasTeacherRoleAsync(eventData.Entity)){awaitCreateOrUpdateTeacherAsync(eventData.Entity,true);}else{awaitCreateOrUpdateTeacherAsync(eventData.Entity,false);}}publicasyncTaskHandleEventAsync(EntityDeletedEto<UserEto>eventData){awaitTryUpdateAndDeactivateTeacherAsync(eventData.Entity);}protectedasyncTask<bool>HasTeacherRoleAsync(UserEtouser){varroles=await_userRoleFinder.GetRolesAsync(user.Id);returnroles.Contains(MySchoolConsts.TeacherRoleName);}protectedasyncTaskCreateOrUpdateTeacherAsync(UserEtouser,boolactive){varteacher=awaitFindTeacherAsync(user);if(teacher==null){teacher=newTeacher(_guidGenerator.Create(),_currentTenant.Id,user.Id,active,user.Name,null);await_teacherRepository.InsertAsync(teacher,true);}else{teacher.Update(active,user.Name,teacher.Age);await_teacherRepository.UpdateAsync(teacher,true);}}protectedasyncTaskTryUpdateAndDeactivateTeacherAsync(UserEtouser){varteacher=awaitFindTeacherAsync(user);if(teacher==null){return;}teacher.Update(false,user.Name,teacher.Age);await_teacherRepository.UpdateAsync(teacher,true);}protectedasyncTask<Teacher>FindTeacherAsync(UserEtouser){returnawait_teacherRepository.FindAsync(x=>x.UserId==user.Id);}}结语最后附一下Super大佬的一些教诲:设计思想要结合自己的业务场景,再考虑如何更契合、优雅、易用、可扩展DDD的哲学之一,你不需要,仅仅是你不需要,但是Abp的IdentityManagement模块是需要的不能只看表象不看里层。说过不能模块化还想着模块化,说过看代码就去看数据表,这种先入为主的思维方式才是真正的问题,根本不是技术的原因…不同的领域观察User,它们关心的数据是不一样的,你不关心email,identity模块会关心,所以你冗余出来的MyUser,可以不存储用户email我也是在阅读文档和对照Super大佬的代码后自己的理解,文中可能某些地方可能与作者设计有差距,还请大家多多理解!也欢迎大家阅读我的AbpvNext系列教程联系作者:加群:867095512@MrChuJi

    .Net

  • CefSharp访问和操纵页面上的内容,可以以编程方式执行JavaScript并将其嵌入到页面中,并在触发JavaScript事件时接收回调。您可以使用CefSharp显示使用HTML5构建的嵌入式UI,或显示远程Web内容和Web应用程序。GoogleChrome浏览器可以使用很多命令行(CommandLine)配置,有些更改功能的行为,而另一些则用于调试或试验。本文主要介绍.NET(C#)中,使用CefSharp时一些常见的错误和获取Javascript(js)方法返回的结果的方法及示例代码。

    .Net

  • 千万级别的表分页查询非常慢,如何改进?

    在实际的软件系统开发过程中,随着使用的用户群体越来越多,表数据也会随着时间的推移,单表的数据量会越来越大。以订单表为例,假如每天的订单量在 4 万左右,那么一个月的订单量就是 120 多万,一年就是 1400 多万,随着年数的增加和单日下单量的增加,订单表的数据量会越来越庞大,订单数据的查询不会像最初那样简单快速,如果查询关键字段没有走索引,会直接影响到用户体验,甚至会影响到服务是否能正常运行!

    Database

  • //由于这里进行了一些api的封装,可参考代码//https://www.jianshu.com/p/80e33d16182f//引用的一些方法放下面了,我一般都是封装到单独的js文件引进来//GetAddress.js引入使用放在最底部//一、这里是获取经纬度(包括调取用户设置,对用户设置的判断)exportdefaultasyncfunctionwxGetLocation(){try{//小程序获取地理位置letre...

    小程序

  • 青龙面板 企业微信应用推送

    #mermaid-svg-0OOhMjh6Wtew3Yco.label{font-family:'trebuchetms',verdana,arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-0OOhMjh6Wtew3Yco.labeltext{fill:#333}#mermaid-svg-0OOhMjh6Wtew3Yco.noderect,#mermaid-svg-0OOhMjh6Wt

    小程序

  • 2021目标期望没达到预期,今天过后所有的期待与努力无最爱、无例外、往事清零,一起跨入2022,续上昨日的期

    Life

  • 1打开ps,点击文件。点击新建,新建画布。2点击左侧矩形工具,画一个矩形。3再按住alt键再画一个矩形。4上方路径操作选择合并形状组件。5这样两个形状就会变成一个整体了。6总结如下。END

    开发技巧

  • vscode使用技巧

    1技巧1:右键菜单中“通过code打开”安装vscode后,可以选中任何任何文件或者文件夹,点击右键选择“通过code打开”,可以方便的用vscode打开文件或者查看文件夹下的所有文件2技巧2:在命令行窗口使用code命令打开文件在cmd,powershell,bash中输入“code.”会用vscode打开当前目录下的文件3技巧3:多文件编辑框,同时查看或者编辑多个文件点击右上角的“spliteditor”图标把文件分为多个编辑框4技巧4:vscode命令行框(CommandPalette)commandpalette可以说是vscode的控制中心,vscode的各种功能都可以使用在commandpalette输入命令来执行和实现,输入快捷键可以打开Ctrl+Shift+P5技巧5:查看vscode的快捷键列表使用快捷键可以让vscode的操作变得高效且简单,vscode支持哪些快捷键呢,可以在如下菜单打开查看“File”->"Preference"->"KeyboardShortcuts"6技巧6:安装插件丰富和高质量的插件是让vscode的功能强大的重要原因,点击vscode界面的插件按钮,可以查询,安装,更新自己想要的插件7技巧7:vscode显示中文vscode默认是英文,如何显示中文呢,在插件中输入@category:"languagepacks"(如图所示),然后选择中文,然后在vscode命令框中输入“display”来配置语言8技巧8:使用gitvscode很好的集成了git的功能,先从git代码库(比如github)克隆到本电脑,在vscode打开这个代码库所在的文件夹,就可以在vscode中通过界面化的方式执行git操作,比如commit,diff,push,pull等操作9技巧9:vscodeterminal(vscode命令终端)在“File”->"Terminal"->"NewTerminal"中打开终端,可以像powershell一样在vscode中执行操作系统级别的命令10技巧10:格式化代码快捷键Shift+Alt+F(对文件中所有代码格式化)快捷键Ctrl+KCtrl+F(对选中的代码格式化)也可以在右键菜单中选择对应功能EN

    开发技巧

2024年 04月19日

周五