.Net Core+Entity Framework读写数据

同步操作

查询数据

为了防止连接数过多,忘记及时释放,建议用using方式操作

using (var context = new MySqlTestDBContext())
{
    var blogs = context.Blogs
        .Where(b => b.Url.Contains("dotnet"))
        .ToList();
}

查询数据,使用的是大量的Linq语言,复杂查询也包括Join等多表连接,和Group By后,Sum(),Avg(),Max(),Min(),FirstOrDefault(),LastOrDefault()等聚合函数,具体可查询Linq的语法,这里不再展开

添加数据

using (var context = new MySqlTestDBContext())
{
	var blog = new Blog { Url = "http://example.com" };
	var Id = context.Blogs.Add(blog).Entity.Id;
	context.SaveChanges();
}

使用 DbSet.Add 方法添加实体类的新实例。 调用 SaveChanges 时,数据将插入到数据库中。

更新数据

找到Blogs表中,BlogId为1的数据,将它的Url字段进行更新

using (var context = new MySqlTestDBContext())
{
	var blog = context.Blogs.FirstOrDefault(i=>i.Id==1);
	blog.Url = "http://example.com/blog";
	context.SaveChanges();
}

删除数据

找到Blogs表中,BlogId为1的数据,将它物理删除

using (var context = new MySqlTestDBContext())
{
    var blog = context.Blogs.FirstOrDefault(i=>i.Id==1);
    context.Blogs.Remove(blog);
    context.SaveChanges();
}

事务

对于大多数数据库提供程序,“SaveChanges” 是事务性的。 这意味着所有操作将一起成功或一起失败,绝不会部分的应用这些操作。

using (var context = new MySqlTestDBContext())
{
    // seeding database
    context.Blogs.Add(new Blog { Url = "http://example.com/blog" });
    context.Blogs.Add(new Blog { Url = "http://example.com/another_blog" });
    context.SaveChanges();
}

using (var context = new MySqlTestDBContext())
{
    // add
    context.Blogs.Add(new Blog { Url = "http://example.com/blog_one" });
    context.Blogs.Add(new Blog { Url = "http://example.com/blog_two" });

    // update
    var firstBlog = context.Blogs.First();
    firstBlog.Url = "";

    // remove
    var lastBlog = context.Blogs.Last();
    context.Blogs.Remove(lastBlog);

    context.SaveChanges();
}

异步操作

当在数据库中执行查询时,异步查询可避免阻止线程。 异步查询对于在胖客户端应用程序中保持响应式 UI 非常重要。 异步查询还可以增加 Web 应用程序中的吞吐量,即通过释放线程,以处理 Web 应用程序中的其他请求

查询数据

public async Task<List<Blog>> GetBlogsAsync()
{
    using (var context = new MySqlTestDBContext())
    {
        return await context.Blogs.ToListAsync();
    }
}

数据集除了ToList方法外,还有一个ToListAsync方法,返回的是一个异步的Task对象

保存数据

同理,异步保存也有一个方法SaveChangesAsync(),返回的也是一个异步Task对象

public static async Task AddBlogAsync(string url)
{
    using (var context = new BloggingContext())
    {
        var blog = new Blog { Url = url };
        context.Blogs.Add(blog);
        await context.SaveChangesAsync();
    }
}

.Net Core + EntityFramework连接数据库

在本教程中,将创建一个 .NET Core 控制台应用,该应用使用 Entity Framework Core 对 SQLServer、MySQL数据库执行数据访问。

你可在 Windows 上使用 Visual Studio,或在MacOS上使用Visual Studio For Mac来学习本教程。

运行系统:Windows、MacOS、Linux

.Net Core环境:.Net Core 3.0+

开发架构搭建

首先创建Core控制台应用程序

目标框架选择.Net Core 3.0以上,起个项目名称,(以下用MySqlTest为例子)

创建项目完成后,选中项目,右键NuGet包管理,搜索entityframeworkcore

此时,我们要选择如下的几个包进行安装

Microsoft.EntityFrameworkCore

Microsoft.EntityFrameworkCore.Design

Microsoft.EntityFrameworkCore.Tools

然后,我们要根据我们项目的数据库。选应该使用的包,

如果是MySql数据库,选用

Pomelo.EntityFrameworkCore.MySql

如果是SQL Server数据库,选用

Microsoft.EntityFrameworkCore.SqlServer

最后,我们在搜索NuGet包,输入搜索Microsoft.Extensions.Configuration.Json,进行安装

Microsoft.Extensions.Configuration.Json

(以下用mysql数据库为例)

项目新建完毕后,我们再新建一个项目配置项,选中项目,右键->添加->新增文件->应用程序设置文件,然后把数据库连接字符串放上去

我们给数据库起名为MySqlTestDB,注意不同数据库使用的连接字符串不同

MySql数据库:

Server=localhost;Database=MySqlTestDB;Port=3306;charset=utf8;uid=用户;pwd=密码;

SqlServer数据库:

server=localhost,1433;database=MySqlTestDB;uid=用户;pwd=密码

创建模型和上下文

定义构成模型的上下文类和实体类。

我们在项目里新增“Modles”文件夹,用于存放数据库实体类

新增“Contexts”文件夹,用于存放上下文类

using MySqlTest.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using System.IO;
namespace MySqlTest.Contexts
{
    public class MySqlTestDBContext: DbContext
    {
        public DbSet<Blog> Blogs { get; set; }
        public DbSet<Post> Posts { get; set; }

        private IConfiguration configuration;

        public MySqlTestDBContext()
        {
            configuration = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json").Build();
        }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseMySql(configuration.GetConnectionString("Default"));
        }
    }
}

Models对应着我们数据库里的表集合。

Entity Framework Core 中,基类默认主键名称为Id,那么在实际表设计中主键名称不一定为Id,那我们可以用Column来指定字段映射

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;

namespace MySqlTest.Models
{
    public class Blog
    {
        [Column("BlogId")]
        public int Id { get; set; }

        [Column("Url")]
        public string Url { get; set; }

        public List<Post> Posts { get; } = new List<Post>();
    }
}
using System;
using System.ComponentModel.DataAnnotations.Schema;

namespace MySqlTest.Models
{
    public class Post
    {
        [Column("PostId")]
        public int Id { get; set; }

        [Column("Title")]
        public string Title { get; set; }

        [Column("Content")]
        public string Content { get; set; }
    }
}

创建数据库

以上,我们完成了项目基本的搭建,这时候,我们需要用Entity Framework Core 的命令行工具,创建数据库,首先我们打开终端,定位到项目所在位置,如图所示

然后我们编译项目,输入如下命令(当然,也可以在Visual Studio里面直接编译)

dotnet build

然后我们输入以下命令

dotnet ef migrations add InitialCreate

这时,我们会看见项目里面多了一个文件夹,里面是升级的内容

然后我们在终端输入以下命令

dotnet ef database update

完成之后,我们就可以看见,我们的本地数据库已经有对应的数据库和数据表生成了

数据库添加字段

当然,我们在项目迭代过程中。回遇到数据库新增字段的情况,这时候,我们要先在对应的Modle实体类里面做调整,按Blog类为例,我们新增一个属性Title

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;

namespace MySqlTest.Models
{
    public class Blog
    {
        [Column("BlogId")]
        public int Id { get; set; }

        [Column("Url")]
        public string Url { get; set; }

        [Column("Title")]
        public string Title { get; set; }

        public List<Post> Posts { get; } = new List<Post>();
    }
}

然后,我们回到终端,重新编译(当然,也可以在Visual Studio里面直接编译)

dotnet build

然后我们输入以下命令

dotnet ef migrations add InitialUpdate_Title

然后我们在终端输入以下命令

dotnet ef database update

好了,这时候,我们看下数据库,已经有新的字段出来了

当然,除此之外,migrations 命令还可以回退sql,也可以指定时间范围进行升级和降级,更多功能请参考官方文档
此处不再累赘。

数据库新增表

当然,我们在项目迭代过程中。回遇到数据库新增表的情况,这时候,我们要先在对应的Modle实体类里面新增实体Person

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;

namespace MySqlTest.Models
{
    public class Person
    {
        [Column("PersonId")]
        public int Id { get; set; }

        [Column("CelPhoneNo")]
        public string CelPhoneNo { get; set; }

        [Column("Name")]
        public string Name { get; set; }
    }
}

然后,在上下文里面添加这个属性 public DbSet<Person> Persons { get; set; }

using MySqlTest.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using System.IO;
namespace MySqlTest.Contexts
{
    public class MySqlTestDBContext: DbContext
    {
        public DbSet<Blog> Blogs { get; set; }
        public DbSet<Post> Posts { get; set; }
        public DbSet<Person> Persons { get; set; }

        private IConfiguration configuration;

        public MySqlTestDBContext()
        {
            configuration = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json").Build();
        }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseMySql(configuration.GetConnectionString("Default"));
        }
    }
}

然后,我们回到终端,重新编译(当然,也可以在Visual Studio里面直接编译)

dotnet bulid

然后我们输入以下命令

dotnet ef migrations add InitialAdd_TablePerson

然后我们在终端输入以下命令

dotnet ef database update

当我们有多个数据库DBContext的时候,命令后面带个参数即可

dotnet ef  migrations add xxxx --context XXXDBContext

dotnet ef database update --context XXXDBContext

搭建.Net Core WebAPI应用程序

在本章节,我们将着重介绍,如果搭建一个基于“.Net Core 3.1 WebAPI+EntityFrameWork+数据库”的应用程序

首先,我们需要.Net Core 3.1 WebAPI的应用程序

所需要的工具:

.Net Core 3.1运行开发环境

Visual Studio 2019

MySql 数据库或SqlServe数据库

创建空白解决方案

打开Visual Studio 2019 ->创建新项目,搜索“空白解决方案”,输入要搭建的服务名称,一般为“MYun.BPC.WebAPI.XXX”,如:

MYun.BPC.WebAPI.Basic

创建完成后,打开解决方案,选中,右键->添加->新建解决方案文件架。现阶段我们需要新增2个文件夹

01_Host 用于存放站点

02_Server 业务逻辑类库

完成后,我们就可以添加站点了

创建Action和Query站点

选中01_Host文件架,右键->添加->新建项目,搜索“ASP.NET Core Web”,选中,点击“下一步”,输入项目名称,名称一般为“MYun.BPC.WebAPI.XXX.Action”和“MYun.BPC.WebAPI.XXX.Query”如:

MYun.BPC.WebAPI.Basic.Action 用于处理端提交的操作请求

MYun.BPC.WebAPI.Basic.Query 用于处理端提交的查询请求

点击创建。这时,我们选中框架为“ASP.Net Core 3.1”,应用程序为“API”,Https配置关闭

创建完成后,效果如下:

到此,WabAPI站点创建完成,接下来,我们需要添加下面几个引用库,用来支持我们的站点

MYun.MY.Contract.Data.dll 契约类库,由类库Contract项目编译生成,用于承载返回的对象

Service.dll 框架类库,由类库Contract项目编译生成,用于承载返回对象的基类

此外,我们还需要在NuGet添加

Newtonsoft.Json

的包。用来支持Json对象的序列化

右键单击“解决方案资源管理器” -> “管理 NuGet 包”中的项目

将“包源”设置为“nuget.org”

在搜索框中输入“Newtonsoft.Json”

从“浏览”选项卡中选择“Newtonsoft.Json”包,然后单击“安装”

当前版本为“12.0.3”

为站点生成说明文档

在使用asp.net core 进行api开发完成后,书写api说明文档对于程序员来说想必是件很痛苦的事情吧,但文档又必须写,而且文档的格式如果没有具体要求的话,最终完成的文档则完全取决于开发者的心情。或者详细点,或者简单点。那么有没有一种快速有效的方法来构建api说明文档呢?答案是肯定的, Swagger就是最受欢迎的REST APIs文档生成工具之一!

为什么使用Swagger作为REST APIs文档生成工具

   Swagger 可以生成一个具有互动性的API控制台,开发者可以用来快速学习和尝试API。

   Swagger 可以生成客户端SDK代码用于各种不同的平台上的实现。

   Swagger 文件可以在许多不同的平台上从代码注释中自动生成。

   Swagger 有一个强大的社区,里面有许多强悍的贡献者。

asp.net core中如何使用Swagger生成api说明文档呢

   Swashbuckle.AspNetCore 是一个开源项目,用于生成 ASP.NET Core Web API 的 Swagger 文档。

   NSwag 是另一个用于将 Swagger UI 或 ReDoc 集成到 ASP.NET Core Web API 中的开源项目。 它提供了为 API 生成 C# 和 TypeScript 客户端代码的方法。

下面以Swashbuckle.AspNetCore为例为大家进行展示

右键单击选中站点 -> “管理 NuGet 包”中的项目

将“包源”设置为“nuget.org”

在搜索框中输入“Swashbuckle.AspNetCore”

从“浏览”选项卡中选择“Swashbuckle.AspNetCore”包,然后单击“安装”

当前版本为“5.6.1”

Action和Query两个站点都安装完毕后,我们再右键选中这些站点->属性->生成

XML文档文件,勾选,指定路径bin\Debug\netcoreapp3.1\MYun.BPC.WebAPI.Basic.XXX.xml

如:

bin\Debug\netcoreapp3.1\MYun.BPC.WebAPI.Basic.Query.xml

bin\Debug\netcoreapp3.1\MYun.BPC.WebAPI.Basic.Action.xml

最后,我们打开项目里的Startup.cs文件,新增引用命名空间

using Microsoft.OpenApi.Models;

using Swashbuckle.AspNetCore.Swagger;

using System.IO;

找到ConfigureServices方法。里面添加如下代码

services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo
    {
        Version = "v1", //接口文档版本
        Title = "Myun .NetCore BascQuery API",  //接口文档标题
        Description = "基础模块BaseQuery",   //描述,不同模块自己设计
    });

    // 为 Swagger JSON and UI设置xml文档注释路径
    var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);//获取应用程序所在目录(绝对,不受工作目录影响,建议采用此方法获取路径)

    var ServicexmlPath = Path.Combine(basePath, "Service.xml"); //此为框架契约说明文档
    c.IncludeXmlComments(ServicexmlPath);

    var DataxmlPath = Path.Combine(basePath, "MYun.MY.Contract.Data.xml");  //此为返回对象说明文档
    c.IncludeXmlComments(DataxmlPath);

    var xmlPath = Path.Combine(basePath, "MYun.BPC.WebAPI.Basic.Query.xml");  //此为当前站点说明文档,Query或Action按不同站点具体配置
    c.IncludeXmlComments(xmlPath);
});

找到Configure方法。里面添加如下代码

//启用中间件服务生成Swagger作为JSON终结点
app.UseSwagger();
//启用中间件服务对swagger-ui,指定Swagger JSON终结点
app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint("/swagger/v1/swagger.json", "Myun .NetCore BascQuery API");
});

最终效果如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.Swagger;
using System.IO;

namespace MYun.BPC.WebAPI.Basic.Action
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo
                {
                    Version = "v1", //接口文档版本
                    Title = "Myun .NetCore BascQuery API",  //接口文档标题
                    Description = "基础模块BaseQuery",   //描述,不同模块自己设计
                });

                // 为 Swagger JSON and UI设置xml文档注释路径
                var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);//获取应用程序所在目录(绝对,不受工作目录影响,建议采用此方法获取路径)

                var ServicexmlPath = Path.Combine(basePath, "Service.xml"); //此为框架契约说明文档
                c.IncludeXmlComments(ServicexmlPath);

                var DataxmlPath = Path.Combine(basePath, "MYun.MY.Contract.Data.xml");  //此为返回对象说明文档
                c.IncludeXmlComments(DataxmlPath);

                var xmlPath = Path.Combine(basePath, "MYun.BPC.WebAPI.Basic.Query.xml");  //此为当前站点说明文档,Query或Action按不同站点具体配置
                c.IncludeXmlComments(xmlPath);
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });

            //启用中间件服务生成Swagger作为JSON终结点
            app.UseSwagger();
            //启用中间件服务对swagger-ui,指定Swagger JSON终结点
            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "Myun .NetCore BascQuery API");
            });
        }
    }
}

到此,文档自动生成工具配置完成,我们现在试试效果。

我们打开项目自动生成的控制器WeatherForecastController文件和WeatherForecast文件,将各个方放加上备注说明,如下

接下来,我们右键站点->属性->调试,将“启动浏览器”修改为“swagger/index.html

保存后,点击调试“运行”。然后打开站点http://localhost:port/swagger/index.html看下效果。发现描述字段都已经出来了

注:为了方便后期维护和节约文档撰写时间,所有.NET Core项目的公共可见类和成员,必须要有描述,如果不描述,则编译的时候会产生警告。

统一时间格式

指定当前项目时间格式统一为文本。24小时制“yyyy-MM-dd HH:mm:ss”,选中站点->添加->新增项->类,添加一个DatetimeJsonConverter

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;

namespace MYun.BPC.WebAPI.Basic.Action
{
    public class DatetimeJsonConverter : JsonConverter<DateTime>
    {
        /// <summary>
        /// 读
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="typeToConvert"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            if (reader.TokenType == JsonTokenType.String)
            {
                if (DateTime.TryParse(reader.GetString(), out DateTime date))
                    return date;
            }
            return reader.GetDateTime();
        }

        /// <summary>
        /// 写
        /// </summary>
        /// <param name="writer"></param>
        /// <param name="value"></param>
        /// <param name="options"></param>
        public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
        {
            writer.WriteStringValue(value.ToString("yyyy-MM-dd HH:mm:ss"));
        }
    }
}

打开Startup.cs找到ConfigureServices方法,添加一条记录

services.AddMvc().AddJsonOptions((options) =>
{
     options.JsonSerializerOptions.Converters.Add(new DatetimeJsonConverter());
     options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All);
     options.JsonSerializerOptions.PropertyNamingPolicy = null;
});

最终效果如下

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();

            services.AddMvc().AddJsonOptions((options) =>
            {
                options.JsonSerializerOptions.Converters.Add(new DatetimeJsonConverter());
                options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All);
                options.JsonSerializerOptions.PropertyNamingPolicy = null;
            });

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo
                {
                    Version = "v1", //接口文档版本
                    Title = "Myun .NetCore BascQuery API",  //接口文档标题
                    Description = "基础模块BaseQuery",   //描述,不同模块自己设计
                });

                // 为 Swagger JSON and UI设置xml文档注释路径
                var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);//获取应用程序所在目录(绝对,不受工作目录影响,建议采用此方法获取路径)

                var ServicexmlPath = Path.Combine(basePath, "Service.xml"); //此为框架契约说明文档
                c.IncludeXmlComments(ServicexmlPath);

                var DataxmlPath = Path.Combine(basePath, "MYun.MY.Contract.Data.xml");  //此为返回对象说明文档
                c.IncludeXmlComments(DataxmlPath);

                var xmlPath = Path.Combine(basePath, "MYun.BPC.WebAPI.Basic.Action.xml");  //此为当前站点说明文档,Query或Action按不同站点具体配置
                c.IncludeXmlComments(xmlPath);
            });
        }

这样,我们所有时间格式的输入输出,都统一为“yyyy-MM-dd HH:mm:ss”,我们用已有的WeatherForecastController控制器试试,发现时间结果都变了

指定标准接口和路由

查询请求

查询通用类库说明

QueryResponse 用来存放查询返回结果基类

QueryRequest 用来存放查询请求基类

查询路由指定”XXXQuery/[controller]/[action]”,如下:

[Route(“BasicQuery/[controller]/[action]”)]

创建一个新的查询控制器,举个例子

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Service;
using MYun.MY.Contract.Data.Order;

namespace MYun.BPC.WebAPI.Basic.Query.Controllers
{
    [ApiController]
    [Route("BasicQuery/[controller]/[action]")]
    public class BasicController : ControllerBase
    {
        /// <summary>
        /// 获取订单详情
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [HttpPost]
        public QueryResponse<CPSOrder> GetOrderBySysNo(QueryRequest<CPSOrderQuerySysNo> param)
        {
            QueryResponse<CPSOrder> result = new QueryResponse<CPSOrder>();
            #region 检测param
            if (param == null)
            {
                result.HasError = true;
                result.Fault = new MessageFault() { ErrorCode = 0, ErrorDescription = "GetLJChangeOrderBySysNo接口参数JSON对象不能为空" };
                return result;
            }
            #endregion
            try
            {
                #region 路由到Service
                QueryResponse<CPSOrder> temp = new QueryResponse<CPSOrder>() { Body=new CPSOrder() { OrderSysNo=111, CreateTime=DateTime.Now } };
                if (temp.HasError)
                {
                    result.HasError = true;
                    result.Fault = temp.Fault;
                }
                else
                {
                    result.Paging = temp.Paging;
                    result.Body = temp.Body;
                }
                return result;
                #endregion
            }
            catch (Exception ex)
            {
                result.HasError = true;
                result.Fault = new MessageFault() { ErrorCode = 0, ErrorDescription = ex.Message };
                return result;
            }
        }

        /// <summary>
        /// 获取订单列表
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [HttpPost]
        public QueryResponse<List<CPSOrder>> GetOrderList(QueryRequest<CPSOrderQuery> param)
        {
            QueryResponse<List<CPSOrder>> result = new QueryResponse<List<CPSOrder>>();
            #region 检测param
            if (param == null)
            {
                result.HasError = true;
                result.Fault = new MessageFault() { ErrorCode = 0, ErrorDescription = "GetLJOrderList接口参数JSON对象不能为空" };
                return result;
            }
            #endregion
            try
            {
                #region 路由到Service
                QueryResponse<List<CPSOrder>> temp = new QueryResponse<List<CPSOrder>>() { Body =new List<CPSOrder> { new CPSOrder() { OrderSysNo = 222, CreateTime = DateTime.Now } } };
                if (temp.HasError)
                {
                    result.HasError = true;
                    result.Fault = temp.Fault;
                }
                else
                {
                    result.Paging = temp.Paging;
                    result.Body = temp.Body;
                }
                return result;
                #endregion
            }
            catch (Exception ex)
            {
                result.HasError = true;
                result.Fault = new MessageFault() { ErrorCode = 0, ErrorDescription = ex.Message };
                return result;
            }
        }

    }
}

操作请求

操作通用类库说明

ActionResponse 用来存放操作返回结果基类

ActionRequest 用来存放操作请求基类

操作路由指定”XXXAction/[controller]/[action]”,如下:

[Route(“BasicAction/[controller]/[action]”)]

创建一个新的操作控制器,举个例子

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Service;
using MYun.MY.Contract.Data.Order;

namespace MYun.BPC.WebAPI.Basic.Action.Controllers
{
    [ApiController]
    [Route("BasicAction/[controller]/[action]")]
    public class BasicController : ControllerBase
    {
        /// <summary>
        /// 新增订单
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResponse<int> AddOrderCPS(ActionRequest<OrderCPSAdd> param)
        {
            ActionResponse<int> result = new ActionResponse<int>();
            #region 检测param
            if (param == null)
            {
                result.HasError = true;
                result.Fault = new MessageFault() { ErrorCode = 0, ErrorDescription = "AddOrderRMA接口参数JSON对象不能为空" };
                return result;
            }
            #endregion
            try
            {
                #region 路由到Service
                return new ActionResponse<int> { Body=1 };
                #endregion
            }
            catch (Exception ex)
            {
                result.HasError = true;
                result.Fault = new MessageFault() { ErrorCode = 0, ErrorDescription = ex.Message };
                return result;
            }
        }

        /// <summary>
        /// 编辑订单
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResponse EditOrderCPS(ActionRequest<OrderCPSEdit> param)
        {
            ActionResponse result = new ActionResponse();
            #region 检测param
            if (param == null)
            {
                result.HasError = true;
                result.Fault = new MessageFault() { ErrorCode = 0, ErrorDescription = "EditOrderRMA接口参数JSON对象不能为空" };
                return result;
            }
            #endregion
            try
            {
                #region 路由到Service
                return new ActionResponse();
                #endregion
            }
            catch (Exception ex)
            {
                result.HasError = true;
                result.Fault = new MessageFault() { ErrorCode = 0, ErrorDescription = ex.Message };
                return result;
            }
        }
    }
}

创建业务处理层

新增一个02_Server文件夹用来处理业务逻辑。然后在文件夹下,右键->新建项目

MYun.BPC.WebAPI.XXX.Server文件结构如下

Service 用于承接接口请求

ActionBP用于处理操作逻辑

QueryBP用于处理查询逻辑

Help用于存放帮助类

Transform用于存放翻译类

添加NuGet包,包内有EntityFrameworkCore等相关的引用,以及Newtonsoft.Json,EntityFrameworkCore等知识点,参考《.Net Core + EntityFramework连接数据库》

最后一步,添加相关项目程序集

然后将MYun.BPC.WebAPI.XXX.Query,MYun.BPC.WebAPI.XXX.Action这2个站点,引用MYun.BPC.WebAPI.XXX.Server这个类库