Asp.net Zero 应用实战-官方示例PhoneBook学习1_修改1版

时间:2023-02-14 22:10:35

适用Zero版本:ASP.NET Core & Angular 2+ (aspnet-zero-core-3.1.0)。

该版本官方有两个solution文件夹:Angular(前端) 和 aspnet-core(后台服务)。

在开始以下步骤之前需要能够成功发布程序,对于后台服务只要能运行即可,如有报错可根据提示安装需要的插件。Angular 则比较麻烦,装的东西较多,官方建议用yarn,这个要下载,顺藤摸瓜都安装完即可。

我没有改解决方案名称,仍用的默认solution的名称MyCompanyName.AbpZeroTemplate,所以下面有的文件名跟官网的phonebook示例文档有区别。

修改1版将aspnet-core后台服务project和Angular前端project的步骤分类,这样不需要跳跃性的操作,阅读操作效率更高。本文仅谈实操,不详细解释理论性的东西,因为本文观点认为,实操没问题了,初学者的信心就有了,理解仅仅是时间问题。

一、aspnet-core后台Project步骤如下:

1、 src/***.core/***CoreModule.cs文件中临时禁用多租户。

[DependsOn(typeof(AbpZeroCoreModule))]
public class PhoneBookCoreModule : AbpModule
{
public override void PreInitialize()
{
//some other code... //Enable this line to create a multi-tenant application.
Configuration.MultiTenancy.IsEnabled = false; //some other code...
}
}

2、src/***.core/Localization/AbpZeroTemplate/AbpZeroTemplate.xml (默认的英文字体)中加入代码。如有对应中文,可在对应的中文文件中加入中文名称。其他语言中没加的都默认用英文的。

<text name="PhoneBook">Phone Book</text> 

3、创建实体类person。在.Core内新建文件夹People,然后在People文件夹内新建如下Person.cs类。

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Abp.Domain.Entities.Auditing; namespace Acme.PhoneBook.People
{
[Table("PbPersons")]
public class Person : FullAuditedEntity
{
public const int MaxNameLength = 32;
public const int MaxSurnameLength = 32;
public const int MaxEmailAddressLength = 255; [Required]
[MaxLength(MaxNameLength)]
public virtual string Name { get; set; } [Required]
[MaxLength(MaxSurnameLength)]
public virtual string Surname { get; set; } [MaxLength(MaxEmailAddressLength)]
public virtual string EmailAddress { get; set; }
}
}

4、在.EntityFramework内的****DbContext.cs文件增加如下黄色标记代码。

public class ******DbContext : AbpZeroDbContext<Tenant, Role, User>
{
public virtual IDbSet<Person> Persons { get; set; } //...other code
}

5、用EntityFramework的code first迁移功能更新数据库创建PdPersons表。

在windows command prompt 命令行工具定位到.EntityFramework文件夹。输入:“dotnet ef migrations add "Added_Persons_Table”并回车。

这会在Migrations文件夹中增加一个***Added_Persons_Table.cs类。然后在命令行中输入:“dotnet ef database update”命令,即可在数据库中生成新表。

我在执行这步的时候报错了。提示C:\Program Files\dotnet\shared\Microsoft.NETCore.App 目录里没有1.1.0版本的。原来是我没安装command line版的

.net core 1.1 sdk.官网直接下载即可下载地址:https://www.microsoft.com/net/core#windowscmd 。安装好即可成功更新数据库。

6、为新创建的PdPersons表造点初始数据。

在.EntityFramework空间内的Migrations/seed/host 内新建InitialPeopleCreator.cs类

Asp.net Zero 应用实战-官方示例PhoneBook学习1_修改1版

类代码:

using System.Linq;
using Acme.PhoneBook.EntityFramework;
using Acme.PhoneBook.People; namespace Acme.PhoneBook.Migrations.Seed.Host
{
public class InitialPeopleCreator
{
private readonly PhoneBookDbContext _context; public InitialPeopleCreator(PhoneBookDbContext context)
{
_context = context;
} public void Create()
{
var douglas = _context.Persons.FirstOrDefault(p => p.EmailAddress == "douglas.adams@fortytwo.com");
if (douglas == null)
{
_context.Persons.Add(
new Person
{
Name = "Douglas",
Surname = "Adams",
EmailAddress = "douglas.adams@fortytwo.com"
});
} var asimov = _context.Persons.FirstOrDefault(p => p.EmailAddress == "isaac.asimov@foundation.org");
if (asimov == null)
{
_context.Persons.Add(
new Person
{
Name = "Isaac",
Surname = "Asimov",
EmailAddress = "isaac.asimov@foundation.org"
});
}
}
}
}  

7、在.EntityFramework空间内的Migrations/seed/host 内的InitialHostDbBuilder.cs类里新增如下黄色标记代码。

public class InitialHostDbBuilder
{
//existing codes... public void Create()
{
//existing code...
new InitialPeopleCreator(_context).Create(); _context.SaveChanges();
}
}

然后在命令行中执行代码:“dotnet ef database update ” 即可。查看PdPersons表里已有数据。

8、创建person应用程序服务-----------新建一个接口类。

应用程序服务对应.Application空间,在MyCompanyName.AbpZeroTemplate.Application下面建立文件夹People。

然后在People文件夹中新建IPersonAppService.cs接口类.代码如下:

using Abp.Application.Services;
using Abp.Application.Services.Dto; namespace Acme.PhoneBook.People
{
public interface IPersonAppService : IApplicationService
{
ListResultDto<PersonListDto> GetPeople(GetPeopleInput input);
}
}

9、在People文件夹下面再建立一个文件夹Dto,然后在此新建PersonListDto.cs文件。代码如下:

using Abp.Application.Services.Dto;
using Abp.AutoMapper; namespace MyCompanyName.AbpZeroTemplate.People.Dto
{
[AutoMapFrom(typeof(Person))]
public class PersonListDto : FullAuditedEntityDto
{
public string Name { get; set; } public string Surname { get; set; } public string EmailAddress { get; set; } } public class GetPeopleInput
{
public string Filter { get; set; }
} }

10、在Pepole文件夹下再建立一个PersonAppService.cs文件。代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Abp.Application.Services.Dto;
using Abp.AutoMapper;
using Abp.Domain.Repositories;
using Abp.Extensions;
using Abp.Linq.Extensions;
using MyCompanyName.AbpZeroTemplate.People.Dto; namespace MyCompanyName.AbpZeroTemplate.People
{
public class PersonAppService:AbpZeroTemplateAppServiceBase,IPersonAppService
{
private readonly IRepository<Person> _personRepository; public PersonAppService(IRepository<Person> personRepository)
{
_personRepository = personRepository;
} public async Task CreatePerson(CreatePersonInput input)
{
var person = input.MapTo<Person>();
await _personRepository.InsertAsync(person);
} public ListResultDto<PersonListDto> GetPeople(GetPeopleInput input)
{
var persons = _personRepository
.GetAll()
.WhereIf(
!input.Filter.IsNullOrEmpty(),
p => p.Name.Contains(input.Filter) ||
p.Surname.Contains(input.Filter) ||
p.EmailAddress.Contains(input.Filter)
)
.OrderBy(p => p.Name)
.ThenBy(p => p.Surname)
.ToList(); return new ListResultDto<PersonListDto>(persons.MapTo<List<PersonListDto>>());
}
} }

11、增加Person。

首先再IpersonAppService.cs文件里新增如下代码:

Task CreatePerson(CreatePersonInput input);

然后在Dto文件内新增类CreatePersonInput.cs类,代码如下:

using Abp.AutoMapper;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks; namespace MyCompanyName.AbpZeroTemplate.People.Dto
{
[AutoMapTo(typeof(Person))]
public class CreatePersonInput
{
[Required]
[MaxLength(Person.MaxNameLength)]
public string Name { get; set; } [Required]
[MaxLength(Person.MaxSurnameLength)]
public string Surname { get; set; } [EmailAddress]
[MaxLength(Person.MaxEmailAddressLength)]
public string EmailAddress { get; set; }
} }

12、允许创建person对象的授权。

首先加入允许进入phonebook页的授权。在src/***.core/Authorization/AppPermissions.cs文件中加入常量定义:

public const string Pages_Tenant_PhoneBook = "Pages.Tenant.PhoneBook";

在src/MyCompanyName.AbpZeroTemplate.Application/People里的PersonAppService.cs里加入如下黄色标记代码:

[AbpAuthorize(AppPermissions.Pages_Tenant_PhoneBook)]
public class PersonAppService : PhoneBookAppServiceBase, IPersonAppService
{
//...
}

在src/***.core/Authorization/AppAuthorizationProvider.cs类中定义许可,代码如下:

var phoneBook = pages.CreateChildPermission(AppPermissions.Pages_Tenant_PhoneBook, L("PhoneBook"), multiTenancySides: MultiTenancySides.Tenant);
phoneBook.CreateChildPermission(AppPermissions.Pages_Tenant_PhoneBook_CreatePerson, L("CreateNewPerson"), multiTenancySides: MultiTenancySides.Tenant);

在同目录下的AppPermissions.cs文件中加入常量定义:

public const string Pages_Tenant_PhoneBook_CreatePerson = "Pages.Tenant.PhoneBook.CreatePerson";

13、增加ABP授权属性。

在src/MyCompanyName.AbpZeroTemplate.Application/People里的PersonAppService.cs文件中增加属性标记代码如下

[AbpAuthorize(AppPermissions.Pages_Tenant_PhoneBook_CreatePerson)]
public async Task CreatePerson(CreatePersonInput input)
{
//...
}

14、删除person实体对象。

在IPersonAppService.cs文件中增加代码:

Task DeletePerson(EntityDto input);

在PersonAppService.cs文件中增加代码:

[AbpAuthorize(AppPermissions.Pages_Tenant_PhoneBook_DeletePerson)]
public async Task DeletePerson(EntityDto input)
{
await _personRepository.DeleteAsync(input.Id);
}

另外提醒一下, 要跟创建person的权限设置一样在AppPermissions.cs文件中定义常量Pages_Tenant_PhoneBook_DeletePerson,

且在src/***.core/Authorization/AppAuthorizationProvider.cs类中定义许可,代码如下:

phoneBook.DeleteChildPermission(AppPermissions.Pages_Tenant_PhoneBook_DeletePerson, L("DeletePerson"), multiTenancySides: MultiTenancySides.Tenant);

以后这类增删查改不再赘述权限功能的实现。

15、创建Phone 实体。

在src/*******.core下创建Phone.cs类代码如下

[Table("PbPhones")]
public class Phone : CreationAuditedEntity<long>
{
public const int MaxNumberLength = ; [ForeignKey("PersonId")]
public virtual Person Person { get; set; }
public virtual int PersonId { get; set; } [Required]
public virtual PhoneType Type { get; set; } [Required]
[MaxLength(MaxNumberLength)]
public virtual string Number { get; set; }
}

16、在Person.cs中增加phones字段。

[Table("PbPersons")]
public class Person : FullAuditedEntity
{
//...other properties public virtual ICollection<Phone> Phones { get; set; }
}

17、在.core下增加PhoneType.cs类

public enum PhoneType : byte
{
Mobile,
Home,
Business
}

18、在Entity Framework下的AbpZeroTemplateDbContext.cs增加代码

public virtual IDbSet<Phone> Phones { get; set; }

且用命令行命令:dotnet ef migrations add "Added_Phone"  增加数据库phone表的迁移类。

然后更新数据库,该部分类似操作在上文已有介绍,不赘述。

该部分未完成待续。。。

19、

20、

二、Angular前端Project步骤如下:

1、增加一个新的菜单项。app\shared\layout\side-bar.component.ts (展开side-bar.component.html文件)在dashboard下面加入如下代码
  new SideBarMenuItem("PhoneBook", null, "icon-notebook", "/app/main/phonebook")

2、app\main\main-routing.module.ts  文件中加路由

{ path: 'dashboard', component: DashboardComponent, data: { permission: 'Pages.Tenant.Dashboard' } },

{ path: 'phonebook', component: PhoneBookComponent }

此时phoneBookComponent报错,先忽略不管。

3、在app/main中新建一个phonebook文件夹并创建phonebook.component.ts文件,代码如下:

import { Component, Injector } from '@angular/core';
import { AppComponentBase } from '@shared/common/app-component-base';
import { appModuleAnimation } from '@shared/animations/routerTransition'; @Component({
templateUrl: './phonebook.component.html',
animations: [appModuleAnimation()]
})
export class PhoneBookComponent extends AppComponentBase { constructor(
injector: Injector
) {
super(injector);
} }

4、解决第2步的报错问题。在main-routing.module.ts加入import代码:

import { PhoneBookComponent } from './phonebook/phonebook.component';

5、在app/main/phonebook中新建 phonebook.component.html文件,代码如下:

<div [@routerTransition]>
<div class="row margin-bottom-5">
<div class="col-xs-12">
<div class="page-head">
<div class="page-title">
<h1>
<span>{{l("PhoneBook")}}</span>
</h1>
</div>
</div>
</div>
</div> <div class="portlet light margin-bottom-0">
<div class="portlet-body"> <p>PHONE BOOK CONTENT COMES HERE!</p> </div>
</div>
</div>

6、在app/main/main.module.ts文件中添加下面有黄色标记的代码。

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms'; import { ModalModule, TabsModule, TooltipModule } from 'ng2-bootstrap'; import { UtilsModule } from '@shared/utils/utils.module'
import { AppCommonModule } from '@app/shared/common/app-common.module' import { MainRoutingModule } from './main-routing.module'
import { MainComponent } from './main.component'
import { DashboardComponent } from './dashboard/dashboard.component';
import { PhoneBookComponent } from './phonebook/phonebook.component'; @NgModule({
imports: [
BrowserModule,
CommonModule,
FormsModule, ModalModule.forRoot(),
TabsModule.forRoot(),
TooltipModule.forRoot(), UtilsModule,
AppCommonModule, MainRoutingModule
],
declarations: [
MainComponent,
DashboardComponent,
PhoneBookComponent
]
})
export class MainModule { }

保存后刷新前端页面点击phone book后可出来如下页面。

Asp.net Zero 应用实战-官方示例PhoneBook学习1_修改1版

7、更新服务端后台服务(后台新增功能代码时执行)。 在dos命令行工具里先定位到angular所在目录路径,然后输入命令:nswag/refresh.bat 执行更新命令。

8、获取person列表。

首先在 shared/service-proxies/service-proxy.module.ts文件中的对应地方加入如下代码:

ApiServiceProxies.PersonServiceProxy

修改phonebook.component.ts里的代码如下面的黄色标记处所示:

import { Component, Injector, OnInit } from '@angular/core';
import { AppComponentBase } from '@shared/common/app-component-base';
import { appModuleAnimation } from '@shared/animations/routerTransition';
import { PersonServiceProxy, PersonListDto, ListResultDtoOfPersonListDto } from '@shared/service-proxies/service-proxies'; @Component({
templateUrl: './phonebook.component.html',
animations: [appModuleAnimation()]
})
export class PhoneBookComponent extends AppComponentBase implements OnInit { people: PersonListDto[] = [];
filter: string = ''; constructor(
injector: Injector,
private _personService: PersonServiceProxy
) {
super(injector);
} ngOnInit(): void {
this.getPeople();
} getPeople(): void {
this._personService.getPeople(this.filter).subscribe((result) => {
this.people = result.items;
});
}
}

再替换phonebook.component.html的 <p>PHONE BOOK CONTENT COMES HERE!</p>代码为下面的黄色标记代码:

<div [@routerTransition]>
<div class="row margin-bottom-5">
<div class="col-xs-12">
<div class="page-head">
<div class="page-title">
<h1>
<span>{{l("PhoneBook")}}</span>
</h1>
</div>
</div>
</div>
</div> <div class="portlet light margin-bottom-0">
<div class="portlet-body"> <h3>{{l("AllPeople")}}</h3> <div class="list-group">
<a *ngFor="let person of people" href="javascript:;" class="list-group-item">
<h4 class="list-group-item-heading">
{{person.name + ' ' + person.surname}}
</h4>
<p class="list-group-item-text">
{{person.emailAddress}}
</p>
</a>
</div> </div>
</div>
</div>

刷新页面

Asp.net Zero 应用实战-官方示例PhoneBook学习1_修改1版

9、新建一个person对象。

首先在phonebook文件夹内创建一个组件create-person-modal.component.ts文件。代码如下:

import { Component, ViewChild, Injector, ElementRef, Output, EventEmitter } from '@angular/core';
import { ModalDirective } from 'ng2-bootstrap';
import { PersonServiceProxy, CreatePersonInput } from '@shared/service-proxies/service-proxies';
import { AppComponentBase } from '@shared/common/app-component-base'; @Component({
selector: 'createPersonModal',
templateUrl: './create-person-modal.component.html'
})
export class CreatePersonModalComponent extends AppComponentBase { @Output() modalSave: EventEmitter<any> = new EventEmitter<any>(); @ViewChild('modal') modal: ModalDirective;
@ViewChild('nameInput') nameInput: ElementRef; person: CreatePersonInput; active: boolean = false;
saving: boolean = false; constructor(
injector: Injector,
private _personService: PersonServiceProxy
) {
super(injector);
} show(): void {
this.active = true;
this.person = new CreatePersonInput();
this.modal.show();
} onShown(): void {
$(this.nameInput.nativeElement).focus();
} save(): void {
this.saving = true;
this._personService.createPerson(this.person)
.finally(() => this.saving = false)
.subscribe(() => {
this.notify.info(this.l('SavedSuccessfully'));
this.close();
this.modalSave.emit(this.person);
});
} close(): void {
this.modal.hide();
this.active = false;
}
}

然后创建同名的html文件 create-person-modal.component.html,代码如下:

<div bsModal #modal="bs-modal" (onShown)="onShown()" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="modal" aria-hidden="true" [config]="{backdrop: 'static'}">
<div class="modal-dialog">
<div class="modal-content">
<form *ngIf="active" #personForm="ngForm" novalidate (ngSubmit)="save()">
<div class="modal-header">
<button type="button" class="close" (click)="close()" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title">
<span>{{l("CreateNewPerson")}}</span>
</h4>
</div>
<div class="modal-body"> <div class="form-group form-md-line-input form-md-floating-label no-hint">
<input #nameInput class="form-control" type="text" name="name" [(ngModel)]="person.name" required maxlength="32">
<label>{{l("Name")}}</label>
</div> <div class="form-group form-md-line-input form-md-floating-label no-hint">
<input class="form-control" type="email" name="surname" [(ngModel)]="person.surname" required maxlength="32">
<label>{{l("Surname")}}</label>
</div> <div class="form-group form-md-line-input form-md-floating-label no-hint">
<input class="form-control" type="email" name="emailAddress" [(ngModel)]="person.emailAddress" required maxlength="255" pattern="^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{1,})+$"> <label>{{l("EmailAddress")}}</label>
</div> </div>
<div class="modal-footer">
<button [disabled]="saving" type="button" class="btn btn-default" (click)="close()">{{l("Cancel")}}</button>
<button type="submit" class="btn btn-primary blue" [disabled]="!personForm.form.valid" [buttonBusy]="saving" [busyText]="l('SavingWithThreeDot')"><i class="fa fa-save"></i> <span>{{l("Save")}}</span></button>
</div>
</form>
</div>
</div>
</div>

接着在main.module.ts类里加入如下黄色标记代码:

...previous imports
import { CreatePersonModalComponent } from './phonebook/create-person-modal.component'; @NgModule({
imports: [
...existing module imports...
],
declarations: [
MainComponent,
DashboardComponent,
PhoneBookComponent,
CreatePersonModalComponent
]
})
export class MainModule { }

最后,在phonebook.component.html文件里加入如下黄色标记代码:

<div [@routerTransition]>
<div class="row margin-bottom-5">
<div class="col-xs-6">
<div class="page-head">
<div class="page-title">
<h1>
<span>{{l("PhoneBook")}}</span>
</h1>
</div>
</div>
</div>
<div class="col-xs-6 text-right">
<button class="btn btn-primary blue" (click)="createPersonModal.show()"><i class="fa fa-plus"></i> {{l("CreateNewPerson")}}</button>
</div>
</div> <div class="portlet light margin-bottom-0">
<div class="portlet-body"> <h3>{{l("AllPeople")}}</h3> <div class="list-group">
<a *ngFor="let person of people" href="javascript:;" class="list-group-item">
<h4 class="list-group-item-heading">
{{person.name + ' ' + person.surname}}
</h4>
<p class="list-group-item-text">
{{person.emailAddress}}
</p>
</a>
</div> </div>
</div>
<createPersonModal #createPersonModal (modalSave)="getPeople()"></createPersonModal>
</div>

10、隐藏未授权的button按钮。

打开phonebook.component.html文件。在button处加入下面的黄色标记代码:

<button *ngIf="isGranted('Pages.Tenant.PhoneBook.CreatePerson')" class="btn btn-primary blue" (click)="createPersonModal.show()"><i class="fa fa-plus"></i> {{l("CreateNewPerson")}}</button>

11、删除peson对象。

修改phonebook.component.html文件,增加如下黄色标记处代码:

...
<h3>{{l("AllPeople")}}</h3> <div class="list-group">
<a *ngFor="let person of people" href="javascript:;" class="list-group-item">
<h4 class="list-group-item-heading">
{{person.name + ' ' + person.surname}}
<button (click)="deletePerson(person)" title="{{l('Delete')}}" class="btn btn-circle btn-icon-only red delete-person" href="javascript:;">
<i class="icon-trash"></i>
</button>
</h4>
<p class="list-group-item-text">
{{person.emailAddress}}
</p>
</a>
</div>
...

12、使用LESS样式将按钮移至右边。

在phonebook文件夹下创建phonebook.component.less样式文件,代码如下:

.list-group-item-heading {
button.delete-person {
float: right;
}
}

在 phonebook.component.ts 文件中引入样式文件,代码如黄色标记:

@Component({
templateUrl: './phonebook.component.html',
styleUrls: ['./phonebook.component.less'],
animations: [appModuleAnimation()]
})

13、在phonebook.component.ts内添加删除功能代码:

deletePerson(person: PersonListDto): void {
this.message.confirm(
this.l('AreYouSureToDeleteThePerson', person.name),
isConfirmed => {
if (isConfirmed) {
this._personService.deletePerson(person.id).subscribe(() => {
this.notify.info(this.l('SuccessfullyDeleted'));
_.remove(this.people, person);
});
}
}
);
}

并且在@Component标记前增加引入代码:

import * as _ from 'lodash';

14、

15、

16、

未完待续。。。

Asp.net Zero 应用实战-官方示例PhoneBook学习1_修改1版的更多相关文章

  1. Asp&period;net Zero 应用实战-官方示例PhoneBook学习1

    适用Zero版本:ASP.NET Core & Angular 2+ (aspnet-zero-core-3.1.0). 该版本官方有两个solution文件夹:Angular(前端) 和 a ...

  2. gRPC官方快速上手学习笔记(c&num;版)

    上手前准备工作 支持操作系统:windows.OS X.Linux.实例采用.net..net core sdk. The .NET Core SDK command line tools. The ...

  3. Asp&period;Net Core 项目实战之权限管理系统(0) 无中生有

    0 Asp.Net Core 项目实战之权限管理系统(0) 无中生有 1 Asp.Net Core 项目实战之权限管理系统(1) 使用AdminLTE搭建前端 2 Asp.Net Core 项目实战之 ...

  4. Asp&period;Net Core 项目实战之权限管理系统(6) 功能管理

    0 Asp.Net Core 项目实战之权限管理系统(0) 无中生有 1 Asp.Net Core 项目实战之权限管理系统(1) 使用AdminLTE搭建前端 2 Asp.Net Core 项目实战之 ...

  5. 【无私分享:ASP&period;NET CORE 项目实战(第十四章)】图形验证码的实现

    目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 很长时间没有来更新博客了,一是,最近有些忙,二是,Core也是一直在摸索中,其实已经完成了一个框架了,并且正在准备在生产环境中 ...

  6. 【无私分享:ASP&period;NET CORE 项目实战(第十三章)】Asp&period;net Core 使用MyCat分布式数据库,实现读写分离

    目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 MyCat2.0版本很快就发布了,关于MyCat的动态和一些问题,大家可以加一下MyCat的官方QQ群:106088787.我 ...

  7. 【无私分享:ASP&period;NET CORE 项目实战(第十二章)】添加对SqlServer、MySql、Oracle的支持

    目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 增加对多数据库的支持,并不是意味着同时对多种数据库操作,当然,后面,我们会尝试同时对多种数据库操作,这可能需要多个上下文,暂且 ...

  8. 【无私分享:ASP&period;NET CORE 项目实战(第十一章)】Asp&period;net Core 缓存 MemoryCache 和 Redis

    目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 经过 N 久反复的尝试,翻阅了网上无数的资料,GitHub上下载了十几个源码参考, Memory 和 Redis 终于写出一个 ...

  9. 【无私分享:ASP&period;NET CORE 项目实战(第七章)】文件操作 FileHelper

    目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 在程序设计中,我们很多情况下,会用到对文件的操作,在 上一个系列 中,我们有很多文件基本操作的示例,在Core中有一些改变,主 ...

随机推荐

  1. Dagger2系列之使用方法

    本系列只讲使用方法和使用中遇到的问题,如果还对dagger2还不了解的童鞋儿可以参考文章: http://www.jianshu.com/p/cd2c1c9f68d4 http://www.jians ...

  2. Lua 学习笔记(七)编译、执行外部代码块

    Lua称为解释型语言的原因:Lua允许在运行源代码之前,先将源代码预编译为一种中间形式.区别解释型语言的主要特征是在于编译器是否是语言运行时库的一部分,即有能力执行动态生成的代码.因为Lua中有dof ...

  3. VMWare MAC系统调整磁盘

    VMware,打开虚拟文件,调整磁盘大小. 从40G调整到80G 进入虚拟机,打开终端 diskutil list;diskutil resizeVolume disk0s2 80GB http:// ...

  4. lazyload&period;js实现图片异步载入

    所谓图片异步加载,意思是不用一次把图片全部加载完,你可以叫它延迟加载,缓冲加载都行. 看看你有没有这种需求:某篇文章图片很多,如果在载入文章时就载入所有图片,无疑会延缓载入速度,让用户等更久,所以,我 ...

  5. TFS2008 安装图解&lpar;详细版本&rpar;(转载)

    由于公司准备上TFS,最近开始学习搭建TFS环境,并为同事讲解TFS的使用,在虚拟 机中搭建测试环境,遇到了很多问题,总结成一篇博客,跟大家交流一下: 我是从微软公司官方网站下载的TFS 2008 1 ...

  6. 配置navigation bar外观

    /* 配置navigation bar外观开始 */ self.navigationBar.translucent = YES; self.navigationBar.titleTextAttribu ...

  7. 敏捷开发(六)- SCRUM全员会议

    本文主要是为了检测你对SCRUM 全员会议的了解和使用程度,通过本文你可以检测一下  1.你们的SCRUM 全员会议的过程和步骤    2.SCRUM 全员会议的输出结果 一.会议目的     组成团 ...

  8. python turtle 书写新年快乐

    文章链接:https://mp.weixin.qq.com/s/xYSKH_KLYfooIoelJH02Cg 农历2018年的最后一篇文章,踏上回家的征途前,推荐一个Python的三方库turtle, ...

  9. docker容器内存占用 之 系统cache&comma;docker下java的内存该如何配置

    缘起: 监控(docker stats)显示容器内存被用完了,进入容器瞅了瞅,没有发现使用内存多的进程,使用awk等工具把容器所有进程使用的内存加起来看看,距离用完还远了去了,何故? 分析: 该不会d ...

  10. 二叉搜索树(BST)

    二叉搜索树需满足以下四个条件: 1.若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 2.若任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值: 3.任意节点的左.右 ...