C# .NET CORE 5.0 Furion框架 搭建 WebAPI

Furion框架
上一章写到如何创建 Furion 模板和脚手架安装以及EF 搭建和自动生
成实体
这一章写一下,如何配置配置文件以及 Application层的 Services和 Core层的Model 和 Repository 做接口调用
C# .NET CORE 5.0 Furion框架 搭建 WebAPI_第1张图片
拿上一章创建的 HelloBlog FurionAPI来说

当创建好项目搭建好EF,下面就让程序跑起来
一、在 HelloBlog.Web.Entry 更改配置文件 appsettings.json
DbConnectionString 连接的字符串

{
  "ConnectionStrings": {
    //"DbConnectionString": "Server=localhost;Database=Furion;User=sa;Password=000000;MultipleActiveResultSets=True;",
    "DbConnectionString": "Server=.;database=Test_Demo;Trusted_Connection=True;MultipleActiveResultSets=True;",
    "Sqlite3ConnectionString": "Data Source=./Test_Demo.db"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information",
      "Microsoft.EntityFrameworkCore": "Information"
    }
  },
  "AllowedHosts": "*"
}

二、在Program 文件 IHostBuilder方法中 添加.Inject() 依赖注册

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

namespace HelloBlog.Web.Entry
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.Inject()
                                     .UseStartup<Startup>();
                });
    }
}

三、在HelloBlog.EntityFramework.Core 层我们需要配置 默认生成的 DefaultDbContext.cs
①设置 [AppDbContext(“数据库连接字符串或者键”, DbProvider.SqlServer【一定要指明数据库类型】)]
② 有的表字段为空需要允许为空 InsertOrUpdateIgnoreNullValues = true; //忽略空值

using Furion.DatabaseAccessor;
using Microsoft.EntityFrameworkCore;

namespace HelloBlog.EntityFramework.Core
{
    [AppDbContext("DbConnectionString", DbProvider.SqlServer)]
    public class DefaultDbContext : AppDbContext<DefaultDbContext>
    {
        public DefaultDbContext(DbContextOptions<DefaultDbContext> options) : base(options)
        {
            InsertOrUpdateIgnoreNullValues = true; //忽略空值
        }
    }
}

四、根据上一章在 HelloBlog.Core 中我们搭建了 EF 自动生成了实体,我们还需要建一个文件夹用于 Repository 的业务逻辑
在这里插入图片描述
①在刚创建的 Repository 文件夹下面 添加Repository. 我这里是 SySDepartmentRepository.sc
Repository编写业务逻辑

using Furion.DatabaseAccessor;
using Furion.DatabaseAccessor.Extensions;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Microsoft.EntityFrameworkCore;

namespace HelloBlog.Core.Repository
{
    public static class SySDepartmentRepository
    {
        //新增操作
        public static void InsertDepartment(this IRepository<SySDepartment> repository, SySDepartment sysdepartment)
        {
            //同步操作
            repository.Insert(sysdepartment);
            //或者 sysdepartment.Insert();
            //或者 repository.Entities.Add(sysdepartment);
            //或者 repository.ChangeEntityState(sysdepartment, EntityState.Added);
        }
        
        public static List<SySDepartment> GetDepartments(this IRepository<SySDepartment> repository, string facility)
        {
            return repository.Where(u => u.Facility.Equals(facility)).ToList();
        }
        
        //复杂的SQL语句查询
        public static string GetTreedata(this IRepository<SySDepartment> repository, string facility, string site, string language)
        {
            //树形菜单绑定
            string str = $@"
            IF NOT OBJECT_ID(N'Tempdb..#T2') IS NULL
                DROP TABLE #T2;
            SELECT  R.id, DE.DEPT_CODE ,
                    VA.MEANING AS name ,
                    DE.UPPER_DEPT,
		            R1.parentId,
		            LINE_ID,
		            ISNULL(DE.MODIFY_DATE,ISNULL(VA.MODIFY_DATE,ISNULL(R.MODIFY_DATE,ISNULL(R1.MODIFY_DATE,DE.CREATE_DATE)))) AS UP_DATE
            INTO #T2
            FROM    SY_S_DEPARTMENT DE
                    INNER JOIN SY_S_GLOBAL_MULTIPLE_LANGUAGE_VALUE VA ON DE.DEPT_CODE = VA.LOOKUP_VALUE
                    INNER JOIN ( SELECT ROW_NUMBER() OVER ( ORDER BY CREATE_DATE,DEPT_CODE ASC ) AS id ,
                                        DEPT_CODE,MODIFY_DATE
                                    FROM   SY_S_DEPARTMENT
                                ) AS R ON R.DEPT_CODE = DE.DEPT_CODE 
                    LEFT JOIN ( SELECT ROW_NUMBER() OVER ( ORDER BY CREATE_DATE,DEPT_CODE ASC ) AS ParentId ,
                                        DEPT_CODE,MODIFY_DATE
                                    FROM   SY_S_DEPARTMENT
                                ) AS R1 ON R1.DEPT_CODE = DE.UPPER_DEPT
            WHERE   VA.LANGUAGE = '{language}' --'zh-cn'
                    AND DE.FACILITY='{facility}'
                    AND DE.SITE='{site}'; 
            --递归
            WITH    menu ( id, name, DEPT_CODE, UPPER_DEPT, parentId,LINE_ID,UP_DATE, Level, px, px2 )
                        AS ( SELECT   id ,
                                    name ,
                                    DEPT_CODE ,
                                    UPPER_DEPT ,
                                    parentId ,
						            LINE_ID,
						            UP_DATE,
                                    0 AS Level ,
                                    id px ,
                                    CAST(id AS NVARCHAR(4000)) px2
                            FROM     #T2
                            WHERE    parentId IS NULL
                            UNION ALL
                            SELECT   A.id ,
                                    A.name ,
                                    A.DEPT_CODE ,
                                    A.UPPER_DEPT ,
                                    A.parentId ,
						            A.LINE_ID,
						            A.UP_DATE,
                                    B.Level + 1 ,
                                    B.px ,
                                    B.px2 + LTRIM(A.id)
                            FROM     #T2 A
                                    INNER JOIN menu B ON A.parentId = B.id
                            )
                SELECT  id ,
                        name ,
                        DEPT_CODE ,
                        UPPER_DEPT ,
                        CASE WHEN parentId IS NULL AND DEPT_CODE='DO' AND id=1 THEN 0
				                WHEN parentId IS NULL AND DEPT_CODE <>'DO'AND id<>1 THEN 1
                                ELSE parentId
                        END AS parentId ,
			            LINE_ID,
                        Level ,
                        px ,
                        px2
                FROM    menu
                ORDER BY LINE_ID ASC,UP_DATE DESC;";
            //var list = str.SqlQuery().AsEnumerable().ToList();
            //var dt =  list.CopyToDataTable();

            var dt = str.SqlQuery();
            return JsonConvert.SerializeObject(dt);
            
        } 
    }
}             

以上InsertDepartment、GetDepartments、GetTreedata 三个方法将有 Services接口 调用,Repository 会以依赖注入方式

五、设置Services 接口方法 、在Services接口实现类中依赖注入Repository
C# .NET CORE 5.0 Furion框架 搭建 WebAPI_第2张图片

Services 接口

using HelloBlog.Core;

namespace HelloBlog.Application
{
    public interface ISystemService
    {
        string GetDescription();

        void InsertDepartment(SySDepartment department);

        string GetTree();
    }
}

Services接口实现

//注入 _sysdepartmentRepository
 private readonly IRepository _sysdepartmentRepository;
 public SystemService(IRepository sysdepartmentRepository)
 {
     _sysdepartmentRepository = sysdepartmentRepository;
 }
using Furion.DatabaseAccessor;
using Furion.DependencyInjection;
using HelloBlog.Core;
using HelloBlog.Core.Repository;

namespace HelloBlog.Application
{
    public class SystemService : ISystemService, ITransient
    {
        //注入 _sysdepartmentRepository
        private readonly IRepository<SySDepartment> _sysdepartmentRepository;
        public SystemService(IRepository<SySDepartment> sysdepartmentRepository)
        {
            _sysdepartmentRepository = sysdepartmentRepository;
        }

        public string GetDescription()
        {
            return "让 .NET 开发更简单,更通用,更流行。";
        }

        public void InsertDepartment(SySDepartment department)
        {
            _sysdepartmentRepository.InsertDepartment(department);
        }

        public string GetTree()
        {
            //调用sysdepartmentRepository 
            var getdepartments = _sysdepartmentRepository.GetDepartments("APAT");

            var gettreedatajson = _sysdepartmentRepository.GetTreedata("APAT", "SZ", "zh-cn");
            return gettreedatajson;
        }
    }
}

方法 InsertDepartment、GetDepartments、GetTreedata 都是调用 ISystemService()
当注入Repository后 就可调用 Repository里面的InsertDepartment、GetDepartments、GetTreedata,实则调用的是 Repository里面的(前提是注入过)

_sysdepartmentRepository.InsertDepartment(department);

var getdepartments = _sysdepartmentRepository.GetDepartments("APAT");

var gettreedatajson = _sysdepartmentRepository.GetTreedata("APAT", "SZ", "zh-cn");

六、运行测试是否能取到数据,查看执行流程
测试GetTreedata 方法
C# .NET CORE 5.0 Furion框架 搭建 WebAPI_第3张图片
已经进入到SystemAppService 的GetTreedata 方法中
C# .NET CORE 5.0 Furion框架 搭建 WebAPI_第4张图片
顺利进入了SystemService 接口基础类上面了,接下来看是否进入注入的Repository 的GetTreedata方法中
C# .NET CORE 5.0 Furion框架 搭建 WebAPI_第5张图片
已经进入GetTreedata 取到数据了
C# .NET CORE 5.0 Furion框架 搭建 WebAPI_第6张图片
显示200
C# .NET CORE 5.0 Furion框架 搭建 WebAPI_第7张图片

另外还可以直接启用
HelloBlog\HelloBlog.Core\bin\Debug\net5.0 下面的 HelloBlog.Web.Entry.exe 程序
C# .NET CORE 5.0 Furion框架 搭建 WebAPI_第8张图片
然后我们可以访问
https://localhost:5001/api/system/Tree
这时候控制台出现 我访问方法所执行SQL 语句
C# .NET CORE 5.0 Furion框架 搭建 WebAPI_第9张图片
C# .NET CORE 5.0 Furion框架 搭建 WebAPI_第10张图片
浏览器也能展示出数据
需要unicode 解码就可以了
C# .NET CORE 5.0 Furion框架 搭建 WebAPI_第11张图片
C# .NET CORE 5.0 Furion框架 搭建 WebAPI_第12张图片
本章的demo

你可能感兴趣的:(Furion,框架,EF,core,.NetCore,.netcore,microsoft,furion,efcore,webapi)