Furion框架
上一章写到如何创建 Furion 模板和脚手架安装以及EF 搭建和自动生
成实体
这一章写一下,如何配置配置文件以及 Application层的 Services和 Core层的Model 和 Repository 做接口调用
拿上一章创建的 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 NULLDROP 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_DATEINTO #T2FROM SY_S_DEPARTMENT DEINNER JOIN SY_S_GLOBAL_MULTIPLE_LANGUAGE_VALUE VA ON DE.DEPT_CODE = VA.LOOKUP_VALUEINNER JOIN ( SELECT ROW_NUMBER() OVER ( ORDER BY CREATE_DATE,DEPT_CODE ASC ) AS id ,DEPT_CODE,MODIFY_DATEFROM 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_DATEFROM SY_S_DEPARTMENT) AS R1 ON R1.DEPT_CODE = DE.UPPER_DEPTWHERE 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)) px2FROM #T2WHERE parentId IS NULLUNION ALLSELECT 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 AINNER 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 0WHEN parentId IS NULL AND DEPT_CODE <>'DO'AND id<>1 THEN 1ELSE parentIdEND AS parentId ,LINE_ID,Level ,px ,px2FROM menuORDER 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
Services 接口
using HelloBlog.Core;namespace HelloBlog.Application
{
public interface ISystemService{
string GetDescription();void InsertDepartment(SySDepartment department);string GetTree();}
}
Services接口实现
//注入 _sysdepartmentRepositoryprivate readonly IRepository<SySDepartment> _sysdepartmentRepository;public SystemService(IRepository<SySDepartment> sysdepartmentRepository){_sysdepartmentRepository = sysdepartmentRepository;}
using Furion.DatabaseAccessor;
using Furion.DependencyInjection;
using HelloBlog.Core;
using HelloBlog.Core.Repository;namespace HelloBlog.Application
{
public class SystemService : ISystemService, ITransient{
//注入 _sysdepartmentRepositoryprivate 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 方法
已经进入到SystemAppService 的GetTreedata 方法中
顺利进入了SystemService 接口基础类上面了,接下来看是否进入注入的Repository 的GetTreedata方法中
已经进入GetTreedata 取到数据了
显示200
另外还可以直接启用
HelloBlog\HelloBlog.Core\bin\Debug\net5.0 下面的 HelloBlog.Web.Entry.exe 程序
然后我们可以访问
https://localhost:5001/api/system/Tree
这时候控制台出现 我访问方法所执行SQL 语句
浏览器也能展示出数据
需要unicode 解码就可以了
本章的demo