当前位置:网站首页>ASP. Net core development experience
ASP. Net core development experience
2022-06-22 07:24:00 【Running water I love】
ASP.NET Core Development experience
- ASP.NET Core Development experience
- One 、c# grammar
- Two 、WebAPI
- 3、 ... and 、EF Core relevant
- 1. EFCore Create the entity class and complete the mapping (CodeFirst)
- Step one : Build a one to many relationship
- Step two : add to nuget package :
- Step three : Add data sources
- Step four : Configuration database connection string
- Step five : Create migration file
- Step six : Start the program , Perform the migration
- Step seven : Load the database connection pool into the service class
- 2. Commonly used Linq Statement summary
- One 、 Query all the data
- Two 、 Single data condition query
- 3、 ... and 、 Set parameter condition query
- Four 、 Multi parameter conditional query
- 5、 ... and 、 Add data to database
- 6、 ... and 、 Update data
- 7、 ... and 、 Delete data
- 8、 ... and 、 Verify that the data exists in the database
- Nine 、 Save database collection
- Ten 、 Complex queries ( Filter ), Fuzzy query ( Search for )
- 11、 ... and 、 Pass in the object as the parameter list of the query
- !!! Experience
- Four 、AutoMapper
ASP.NET Core Development experience
One 、c# grammar
Asynchronous methods
It can be done by async、await、Task Compose a business method that supports asynchrony ,
Use async Define asynchronous methods ,await Define asynchronous functions ,Task Define the asynchronous return result
public async Task<IEnumerable<Company>> GetCompaniesAsync(IEnumerable<Guid> companyIds)
{
if (companyIds == null)
{
throw new ArgumentNullException(nameof(companyIds));
}
return await _context.Companies
.Where(x => companyIds.Contains(x.Id))
.OrderBy(x => x.Name)
.ToListAsync();
}
Common abnormal
throw new ArgumentNullException(nameof(companyIds)); // Judge whether the method parameter is empty
Guid class
GUIDglobally unique identifier( Globally unique identifier )
Equivalent to an algorithm generated ID
Guid.Empty():Guid Structure , Its value is all zero ., Generally used to judge Guid Whether it has been assigned
new Guid(): Return from 00000000-0000-0000-0000-000000000000 Composed of Guid object
Guid.NewGuid(): Returns a set of generated by random numbers Guid object
Guid.Parse(string guidString): Convert the string to Guid object
Console.WriteLine(Guid.Parse("fc6a01da-c1bc-44c6-a36a-d0fb02550af6"));
Two 、WebAPI
1. establish WebAPI Project configuration
To configure Startup.cs
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// Add support for content negotiation (XML)JSON first
services.AddControllers(setup =>
{
setup.ReturnHttpNotAcceptable = true;
}).AddXmlDataContractSerializerFormatters();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// Add simple support for exception handling production environments
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler(appBuilder =>
{
appBuilder.Run(async context =>
{
context.Response.StatusCode = 500;
await context.Response.WriteAsync("Unexpected Error");
});
});
}
// take Https Forward to Http
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
// Be careful : The routing template must be configured separately in the controller
app.UseEndpoints(endpoints => {
endpoints.MapControllers(); });
}
}
Be careful : The routing template must be configured separately in the controller
** Be careful :** If you want to configure content negotiation XML first , The following codes can be configured
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(setup =>
{
setup.ReturnHttpNotAcceptable = true;
// OutputFormatters Different support for content negotiation can be added in , The first is the default serial number support
setup.OutputFormatters
.Add(new XmlDataContractSerializerOutputFormatter());
});
}
2. To configure WebAPI Controller and general routing configuration
Routing configuration , Write on the notes
Simple routing configuration
[ApiController]
[Route("api/companies")]
public class CompaniesController : ControllerBase
{
[HttpGet("api/companies")]
public async Task<ActionResult> GetCompanies()
{
var companies = await _companyRepository.GetCompaniesAsync();
return Ok(companyDtos);
}
[HttpGet("{companyId}")]
public async Task<ActionResult> GetCompany(Guid companyId)
{
var company = await _companyRepository.GetCompanyAsync(companyId);
if(company == null)
{
return NotFound();
}
return Ok(companyDtos);
}
}
Optional [Route("api/companies")] Configure to [Route("api/[controller]")]
This is the time ,[controller] Consistent with the controller name .
Can be [HttpGet("{companyId}")] Write separately :
[HttpGet]
[Route("{companyId}")]
It can be globally simplified to
[ApiController]
[Route("api/companies")]
public class CompaniesController : ControllerBase
{
[HttpGet]
public async Task<ActionResult> GetCompanies()
{
var companies = await _companyRepository.GetCompaniesAsync();
return Ok(companyDtos);
}
[HttpGet]
public async Task<ActionResult> GetCompany(Guid companyId)
{
var company = await _companyRepository.GetCompanyAsync(companyId);
if(company == null)
{
return NotFound();
}
return Ok(companyDtos);
}
}
3. Configure the default startup page
Properties/launchSettings.json
Configure the following "launchUrl": "api/companies"
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "api/companies",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"RoutineApi2": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "api/companies",
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
4.Enity Model And externally oriented Model
In one case , take EF Built in Model, External output and interface parameter transfer Mode(DTO) Separate .
Create three folders to store three different types of storage Model Folder
- RoutineApi2/Entities
- Company.cs
- Employee.cs
- Gender.cs
- Models
- CompanyDto.cs
- EmployeeDto.cs
- DtoParameters
- CompanyDtoParameters
- EmployeeDtoParameters
3、 ... and 、EF Core relevant
1. EFCore Create the entity class and complete the mapping (CodeFirst)
Step one : Build a one to many relationship
- RoutineApi2/Entities
- Company.cs
- Employee.cs
- Gender.cs
public class Company
{
// To configure ID
public Guid Id {
get; set; }
public string Name {
get; set; }
public string Introduction {
get; set; }
// add to Employees aggregate ( One to many )
public ICollection<Employee> Employees {
get; set; }
}
public class Employee
{
// To configure ID
public Guid Id {
get; set; }
public Guid CompanyId {
get; set; }
public string EmployeeNo {
get; set; }
public string FirstName {
get; set; }
public string LastName {
get; set; }
public Gender Gender {
get; set; }
public DateTime DataOfBirth {
get; set; }
// Configure an external association
public Company Company {
get; set; }
}
public enum Gender
{
male = 1,
Woman = 2
}
Step two : add to nuget package :
Microsoft.EntityFrameworkCore.SqlServer
Microsoft.EntityFrameworkCore.Sqlite
Microsoft.EntityFrameworkCore.Tools
Step three : Add data sources
RoutineApi2/Data/RoutineDbContext.cs
namespace RoutineApi2.Data
{
public class RoutineDbContext : DbContext
{
// Default configuration injection
public RoutineDbContext(DbContextOptions<RoutineDbContext> options) : base(options)
{
}
// Database dataset Injection
public DbSet<Company> Companies {
get; set; }
public DbSet<Employee> Employees {
get; set; }
// Configure associations and restrictions
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Company>()
.Property(x => x.Name).IsRequired().HasMaxLength(100);
modelBuilder.Entity<Company>()
.Property(x => x.Introduction).IsRequired().HasMaxLength(500);
modelBuilder.Entity<Employee>()
.Property(x => x.EmployeeNo).IsRequired().HasMaxLength(10);
modelBuilder.Entity<Employee>()
.Property(x => x.FirstName).IsRequired().HasMaxLength(50);
modelBuilder.Entity<Employee>()
.Property(x => x.LastName).IsRequired().HasMaxLength(50);
modelBuilder.Entity<Employee>()
.HasOne(x => x.Company)
.WithMany(x => x.Employees)
// When Employee Exist in Company, Not delete Company
.HasForeignKey(x => x.CompanyId).OnDelete(DeleteBehavior.Restrict);
// Configure seed data
modelBuilder.Entity<Company>().HasData(
new Company
{
Id = Guid.Parse("25dbd774-ae0e-44d2-94a1-58d5805da533"),
Name = "Microsoft",
Introduction = "Great Company",
},
new Company
{
Id = Guid.Parse("2aea0972-6a03-4f3c-9672-04fa2ca99110"),
Name = "Google",
Introduction = "Don't be evil"
},
new Company
{
Id = Guid.Parse("c6fbfe31-590f-477f-a87a-3c68423909c6"),
Name = "Alipapa",
Introduction = "Fubao Company"
}
);
modelBuilder.Entity<Employee>().HasData(
new Employee
{
Id = Guid.Parse("410f4bbe-e109-49d4-932a-e3cfe29f53ed"),
CompanyId = Guid.Parse("25dbd774-ae0e-44d2-94a1-58d5805da533"),
DataOfBirth = new DateTime(1966,1,2),
EmployeeNo = "MSFT231",
FirstName = "Nick",
LastName = "Carer",
Gender = Gender. male
},
new Employee
{
Id = Guid.Parse("ba5790e1-765d-4e71-8795-edd24398f8e4"),
CompanyId = Guid.Parse("25dbd774-ae0e-44d2-94a1-58d5805da533"),
DataOfBirth = new DateTime(1996,2,3),
EmployeeNo = "MSFT245",
FirstName = "Vince",
LastName = "Carter",
Gender = Gender. male
},
new Employee
{
Id = Guid.Parse("1a5b77ee-9e43-46ba-b1dc-3b5c32c647d4"),
CompanyId = Guid.Parse("2aea0972-6a03-4f3c-9672-04fa2ca99110"),
DataOfBirth = new DateTime(1986,2,1),
EmployeeNo = "MSFT215",
FirstName = "Machal",
LastName = "Jeckson",
Gender = Gender. male
}
);
}
}
}
Step four : Configuration database connection string
One 、SQLServer edition :
appsettings.json
"ConnectionStrings": {
"DockerDBConnection": "Data Source=127.0.0.1;Initial Catalog=CompanyDB;User ID=sa;Password=<Admin123456>",
"LocalDockerDBConnection": "Data Source=192.168.1.104;Initial Catalog=CompanyDB;User ID=sa;Password=<Admin123456>",
"MSDBConnection": "Server=(localdb)\\mssqllocaldb;Database=CompanyDB;Trusted_Connection=True;MultipleActiveResultSets=true",
"SqlServerConnection": "Data Source = myServerAddress;Initial Catalog = myDataBase;User Id = myUsername;Password = myPassword;"
}
Startup.cs
public Startup(IConfiguration configuration)
{
_configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
// Database connection service
services.AddDbContextPool<AppDbContent>(
option => option
.UseSqlServer(_configuration.GetConnectionString("LocalDockerDBConnection")));
}
Two 、Sqlite edition
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContextPool<RoutineDbContext>(
option =>
{
option.UseSqlite("Data Source=routine.db");
});
}
Step five : Create migration file
VSCode Development
Shell The input
$ dotnet ef migrations add InitialMigration
VS Development
Open the package console
Enter the command
$ add-migration
You can see the following files in the directory
- Migrations
- 20200511033121_InitialMigration.cs
- RoutineDbContextModelSnapshot.cs
Step six : Start the program , Perform the migration
Step seven : Load the database connection pool into the service class
public class CompanyRepository : ICompanyRepository
{
private readonly RoutineDbContext _context;
public CompanyRepository(RoutineDbContext context)
{
_context = context ?? throw new ArgumentException(nameof(context));
}
}
2. Commonly used Linq Statement summary
One 、 Query all the data
No parameter , Return all data sets directly
public async Task<IEnumerable<Company>> GetCompaniesAsync()
{
return await _context.Companies.ToListAsync();
}
Two 、 Single data condition query
Single parameter , Return single data
public Task<Company> GetCompanyAsync(Guid companyId)
{
if (companyId == Guid.Empty)
{
throw new ArgumentNullException(nameof(companyId));
}
// FirstOrDefaultAsync : Returns a unique object asynchronously
return _context.Companies.FirstOrDefaultAsync(x => x.Id == companyId);
}
3、 ... and 、 Set parameter condition query
Parameters are data sets , Return data set
public async Task<IEnumerable<Company>> GetCompaniesAsync(IEnumerable<Guid> companyIds)
{
if (companyIds == null)
{
throw new ArgumentNullException(nameof(companyIds));
}
return await _context.Companies
.Where(x => companyIds.Contains(x.Id))
.OrderBy(x => x.Name)
.ToListAsync();
}
Four 、 Multi parameter conditional query
Parameters : multi-parameter , return : Single data object
public async Task<Employee> GetEmployeesAsync(Guid companyId, Guid employeeId)
{
if (companyId == Guid.Empty)
{
throw new ArgumentNullException(nameof(companyId));
}
if (companyId == Guid.Empty)
{
throw new ArgumentNullException(nameof(companyId));
}
// Multiconditional query
return await _context.Employees
.FirstOrDefaultAsync(x => x.CompanyId == companyId && x.Id == employeeId);
}
5、 ... and 、 Add data to database
public void AddCompany(Company company)
{
if (company == null)
{
throw new ArgumentNullException(nameof(company));
}
// Process incoming data
company.Id = Guid.NewGuid();
foreach (var employee in company.Employees)
{
employee.Id = Guid.NewGuid();
}
// Add data
_context.Companies.Add(company);
}
6、 ... and 、 Update data
public void UpdateCompany(Company company)
{
// _context.Entry(company).State = EntityState.Modified; Don't write
}
7、 ... and 、 Delete data
public void DeleteCompany(Company company)
{
if (company == null)
{
throw new ArgumentNullException(nameof(company));
}
// Delete data
_context.Companies.Remove(company);
}
8、 ... and 、 Verify that the data exists in the database
public async Task<bool> CompanyIsExistsAsync(Guid companyId)
{
if (companyId == Guid.Empty)
{
throw new ArgumentNullException(nameof(companyId));
}
return await _context.Companies.AnyAsync(x => x.Id == companyId);
}
Nine 、 Save database collection
public async Task<bool> SaveAsync()
{
return await _context.SaveChangesAsync() >= 0;
}
Ten 、 Complex queries ( Filter ), Fuzzy query ( Search for )
public async Task<IEnumerable<Employee>>
// company ID( Query criteria ), Employee gender ( Filter ), Fuzzy query ( Search for )q
GetEmployeesAsync(Guid companyId, string genderDisplay,string q)
{
if (companyId == Guid.Empty)
{
throw new ArgumentNullException(nameof(companyId));
}
// If the filter and search criteria passed in are empty , Regular short answer queries
if (string.IsNullOrWhiteSpace(genderDisplay) && string.IsNullOrWhiteSpace(q))
{
return await _context.Employees
.Where(x => x.CompanyId == companyId)
.OrderBy(x => x.EmployeeNo)
.ToListAsync();
}
// First, perform a simple query and save the result as items
var items =
_context.Employees.Where(x => x.CompanyId == companyId);
if (!string.IsNullOrWhiteSpace(genderDisplay))
{
// Trim() Remove the spaces on both sides
genderDisplay = genderDisplay.Trim();
// Convert the passed in parameter to Enum type
var gender = Enum.Parse<Gender>(genderDisplay);
items = items.Where(x => x.Gender == gender);
}
if (!string.IsNullOrWhiteSpace(q))
{
q = q.Trim();
// Any match will do || or
items = items.Where(x => x.EmployeeNo.Contains(q)
|| x.FirstName.Contains(q)
|| x.LastName.Contains(q)
);
}
return await items.OrderBy(x => x.EmployeeNo)
.ToListAsync();
}
11、 ... and 、 Pass in the object as the parameter list of the query
DtoParameters/CompanyDtoParameters.cs
public class CompanyDtoParameters
{
public string CompanyName {
get; set; }
public string SearchTerm {
get; set; }
}
public async Task<IEnumerable<Company>> GetCompaniesAsync(CompanyDtoParameters parameters)
{
if (parameters == null)
{
throw new ArgumentNullException(nameof(parameters));
}
if (string.IsNullOrWhiteSpace(parameters.CompanyName) &&
string.IsNullOrWhiteSpace(parameters.SearchTerm))
{
return await _context.Companies.ToListAsync();
}
// Save the database connection string collection temporarily , The query method is not triggered here
var queryExpression = _context.Companies as IQueryable<Company>;
if (!string.IsNullOrWhiteSpace(parameters.CompanyName))
{
parameters.CompanyName = parameters.CompanyName.Trim();
queryExpression = queryExpression
.Where(x => x.Name == parameters.CompanyName);
}
if (!string.IsNullOrWhiteSpace(parameters.SearchTerm))
{
parameters.SearchTerm = parameters.SearchTerm.Trim();
// Fuzzy query
queryExpression = queryExpression
.Where(x => x.Name.Contains(parameters.SearchTerm)
|| x.Introduction.Contains(parameters.SearchTerm));
}
// Only here can we really query the database
return await queryExpression.ToListAsync();
}
!!! Experience
Summary of common methods :
One 、 After the parameter is passed in, you need to determine whether it is empty
// The incoming type is Guid
if (companyId == Guid.Empty)
{
throw new ArgumentNullException(nameof(companyId));
}
// The incoming type is object
if (companyIds == null)
{
throw new ArgumentNullException(nameof(companyIds));
}
// The incoming type is string
if (string.IsNullOrWhiteSpace(genderDisplay) && string.IsNullOrWhiteSpace(q)){
}
Two 、 The query result is unique , use FirstOrDefaultAsync(), A special kind Where
return _context.Companies.FirstOrDefaultAsync(x => x.Id == companyId);
3、 ... and 、 The query result is not unique , use Where
Four 、 The query results need to be sorted , have access to OrderBy() and OrderByDescending(), Sort according to the positional parameter
return await _context.Companies
.Where(x => companyIds.Contains(x.Id))
.OrderBy(x => x.Name)
.ToListAsync();
5、 ... and 、 Parameters should be first Trim Remove the extra space and then perform the query operation
6、 ... and 、 Determine whether the data exists in the database , have access to AnyAsync Method , Be similar to Where, But what it returns is Bool type
return await _context.Companies.AnyAsync(x => x.Id == companyId);
7、 ... and 、 To add, delete and delete data, you can use DBSet.Add(Object) and DBSet.Remove(Object)
Four 、AutoMapper
When frequent need for DTO When mapping data , Need new a large number of DTO object , Such code is redundant .
have access to AutoMapper Finish right DTO Automatic mapping of .
Step one 、 add to AutoMapper Of Nuget package
AutoMapper.Extensions.Microsoft.DependencyInjection
Step two 、 stay Startup Of ConfigureService register Mapper Containers , Register default configuration
services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
Step three 、 To configure Mapper mapping
establish Profiles Folder
- Profiles
- RoutineApi2/Profiles/CompanyProfile.cs
- RoutineApi2/Profiles/EmployeeProfile.cs
Source type :
public class Company
{
public Guid Id {
get; set; }
public string Name {
get; set; }
public string Introduction {
get; set; }
public ICollection<Employee> Employees {
get; set; }
}
public class Employee
{
public Guid Id {
get; set; }
public Guid CompanyId {
get; set; }
public string EmployeeNo {
get; set; }
public string FirstName {
get; set; }
public string LastName {
get; set; }
public Gender Gender {
get; set; }
public DateTime DataOfBirth {
get; set; }
public Company Company {
get; set; }
}
public enum Gender
{
male = 1,
Woman = 2
}
public class CompanyDto
{
public Guid Id {
get; set; }
public string CompanyName {
get; set; }
}
public class EmployeeDto
{
public Guid Id {
get; set; }
public Guid CompanyId {
get; set; }
public string EmployeeNo {
get; set; }
public string Name {
get; set; }
public Gender GenderDisplay {
get; set; }
public int Age {
get; set; }
}
To configure Mapper
public class CompanyProfile : Profile
{
public CompanyProfile()
{
// Original type and target type
CreateMap<Company, CompanyDto>()
.ForMember(
dest => dest.CompanyName,
opt
=> opt.MapFrom(src => src.Name));
}
}
public class EmployeeProfile : Profile
{
public EmployeeProfile()
{
CreateMap<Employee, EmployeeDto>()
.ForMember(
dest
=> dest.Name,
opt
=> opt.MapFrom(src
=> $"{src.FirstName} {src.LastName}"))
.ForMember(
dest
=> dest.GenderDisplay,
opt
=> opt.MapFrom(src
=> src.Gender.ToString()))
.ForMember(
dest
=> dest.Age,
opt
=> opt.MapFrom(src
=> DateTime.Now.Year - src.DataOfBirth.Year));
}
}
Step five 、 add to Mapper To the controller
public class CompaniesController : ControllerBase
{
private readonly ICompanyRepository _companyRepository;
private readonly IMapper _mapper;
public CompaniesController(ICompanyRepository companyRepository, IMapper mapper)
{
_companyRepository = companyRepository ??
throw new ArgumentNullException(nameof(companyRepository));
_mapper = mapper ?? throw new ArgumentException(nameof(mapper));
}
[HttpGet]
[HttpHead]
public async Task<ActionResult<IEnumerable<CompanyDto>>>
GetCompanies([FromQuery]CompanyDtoParameters parameters)
{
var companies = await _companyRepository.GetCompaniesAsync(parameters);
// Automatically complete the mapping , The parameter is the source Model, The generic is the target type
var companyDtos = _mapper.Map<IEnumerable<CompanyDto>>(companies);
return Ok(companyDtos);
}
[HttpGet("{companyId}")]
public async Task<ActionResult<CompanyDto>> GetCompany(Guid companyId)
{
var company = await _companyRepository.GetCompanyAsync(companyId);
if (company == null)
{
return NotFound();
}
return Ok(_mapper.Map<CompanyDto>(company));
}
}
边栏推荐
- antd——a-upload-dragger拖拽上传组件——基础积累
- Tpflow v6.0.6 official release
- CNN model collection | RESNET variants -wideresnet interpretation
- Chromedriver所有版本下載
- Notes on algebra 10.1: understanding of symmetric polynomials and derivation of cubic resolvents
- What if the finder fails to respond continuously? Finder unresponsive solution tutorial
- Canoe learning notes (6) diagram of logging block data recording module
- Speed planning generation of coursera self driving car Part4 motion planning
- selenium防爬和模拟手机浏览器
- Greek alphabet - system / service name commonly used in development - Collection
猜你喜欢

C语言实现的简易考试系统

【GAN】SentiGAN IJCAI’18 Distinguished Paper

New year's Day mall material Icon

Batch collection, grab Taobao baby, upload and collect commodity software

Coursera self driving car Part4 motion planning finalproject principle and key code analysis

ROS QT environment construction

架构图颜色搭配

Canoe learning notes (6) diagram of logging block data recording module

Téléchargement de toutes les versions de chromedriver

MySQL面试真题(十九)——抖音-选出每个月有连续登录2天的用户名单
随机推荐
Parameter curve notes of coursera self driving car Part4 motion planning
Fundamentals of neural network (notes, for personal use)
Greek alphabet - system / service name commonly used in development - Collection
Wechat applet service provider sub merchant payment order interface
On vector norm
Flutter input field maxlines dynamic change
记一次内网渗透测试实训总结
[v4.3] the applet fails to receive the subscription message, and the coupon time on the product details page is displayed incorrectly
微信小游戏(四)
Common evaluation indicators of recommended system: ndcg, recall, precision, hit rate
微信小程序服务商下子商户支付下单接口
【GAN】SentiGAN IJCAI’18 Distinguished Paper
5g NR PWS system
MySQL面试真题(十八)——经营分析实战
JS implementation of random generation of 16 bit key -- Basic accumulation
vue连接mysql数据库失败
Image interpolation (nearest neighbor, bilinear)
【实习】跨域问题
Choco usage notes -- how to set the default package installation location of choco
Résumé semestriel du programmeur de 33 ans