支持多数据库。报表可以定义使用的数据库,使用myjs.GetDAta方法获取数据。

This commit is contained in:
falcon 2021-05-31 15:11:06 +08:00
parent 57d7a71932
commit 92abb7e2de
9 changed files with 149 additions and 31 deletions

View File

@ -1,13 +1,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using Falcon.StoredProcedureRunner;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using ReportService.Database; using ReportService.Database;
using ReportService.Models; using ReportService.Models;
using ReportService.Models.ReportApi;
namespace ReportService.Controllers.api namespace ReportService.Controllers.api
{ {
@ -16,9 +15,8 @@ namespace ReportService.Controllers.api
public class ReportApiController:Controller public class ReportApiController:Controller
{ {
public IWebHostEnvironment Env { get; private set; } public IWebHostEnvironment Env { get; private set; }
public RSDbContext Db { get; set; }
public ILogger Logger { get; set; } public ILogger Logger { get; set; }
public IRunner DbRunner { get; set; } public DbContextFactory DbFactory { get; set; }
/// <summary> /// <summary>
/// 报表存放位置 /// 报表存放位置
@ -29,11 +27,10 @@ namespace ReportService.Controllers.api
} }
} }
public ReportApiController(ILogger<ReportApiController> logger,IWebHostEnvironment env,RSDbContext db,IRunner r) { public ReportApiController(ILogger<ReportApiController> logger,IWebHostEnvironment env,DbContextFactory dbFactory) {
this.Logger = logger; this.Logger = logger;
this.Env = env; this.Env = env;
this.Db = db; this.DbFactory = dbFactory;
this.DbRunner = r;
} }
/// <summary> /// <summary>
@ -123,8 +120,19 @@ namespace ReportService.Controllers.api
/// <param name="sql">要执行的sql语句</param> /// <param name="sql">要执行的sql语句</param>
/// <returns>json对象</returns> /// <returns>json对象</returns>
public object GetResult(string sql) { public object GetResult(string sql) {
var result = this.DbRunner.RunRaw(this.Db,sql); return GetData(new GetDataData {
this.Logger.LogInformation($"GetResult:\n{sql}\n{result}"); DbName = "ReportService",
Sql = sql,
});
}
/// <summary>
/// 从数据请求数据。
/// </summary>
/// <param name="data">请求数据模型</param>
/// <returns>返回json格式数据</returns>
public object GetData([FromBody]GetDataData data) {
var result = this.DbFactory.RunRawSql(data.DbName,data.Sql);
this.Logger.LogInformation($"GetData:\n{data.Sql}\n{result}");
return Content(result,"application/json; charset=utf-8"); return Content(result,"application/json; charset=utf-8");
} }

View File

@ -0,0 +1,61 @@
using System;
using System.Collections.Generic;
using Falcon.StoredProcedureRunner;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
namespace ReportService.Database
{
/// <summary>
/// 数据库上下文工厂
/// </summary>
public class DbContextFactory
{
/// <summary>
/// 数据库上下文集合
/// </summary>
public Dictionary<string,DbContextOptions> List { get; set; } = new();
/// <summary>
/// 数据库执行器
/// </summary>
public IRunner DbRunner { get; set; }
/// <summary>
/// 通过提供配置节点实例化数据库上下文工厂
/// </summary>
/// <param name="config">配置节点</param>
/// <param name="runner">数据库语句执行器</param>
public DbContextFactory(IConfigurationSection config,IRunner runner) {
foreach(var item in config.GetChildren()) {
DbContextOptionsBuilder builder = new();
builder.UseSqlServer(item.Value);
this.List.Add(item.Key,builder.Options);
}
this.DbRunner = runner;
}
/// <summary>
/// 获取数据库上下文
/// </summary>
/// <param name="name">节点定义的数据库名称</param>
/// <returns>数据上下文</returns>
public DbContext GetContext(string name) {
if(List.TryGetValue(name,out var option)) {
return new DbContext(option);
}
throw new Exception("使用的数据库名称错误!");
}
/// <summary>
/// 在指定数据库上执行原始sql语句并返回json格式数据。注意防止sql注入攻击
/// </summary>
/// <param name="dbName">数据库名称</param>
/// <param name="sql">要执行的sql语句</param>
/// <returns>json格式的数据库返回数据</returns>
public string RunRawSql(string dbName,string sql) {
if(this.DbRunner == null) {
throw new Exception("执行器注册错误没有实例化IRunner执行器");
}
return this.DbRunner.RunRaw(GetContext(dbName),sql);
}
}
}

View File

@ -0,0 +1,27 @@
using Falcon.StoredProcedureRunner;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace ReportService.Database
{
/// <summary>
/// 数据上下文工厂服务集合扩展
/// </summary>
public static class DbContextFactoryServiceCollectionEx
{
/// <summary>
/// 注册数据库工厂
/// </summary>
/// <param name="services">服务集合</param>
/// <param name="sectionKey">配置文件节点</param>
/// <returns>服务集合</returns>
public static IServiceCollection AddDbContextFactory(this IServiceCollection services,string sectionKey) {
services.AddSingleton(sp => {
var section = sp.GetService<IConfiguration>().GetSection(sectionKey);
var runner = sp.GetService<IRunner>();
return new DbContextFactory(section,runner);
});
return services;
}
}
}

View File

@ -1,14 +0,0 @@
using Microsoft.EntityFrameworkCore;
namespace ReportService.Database
{
/// <summary>
/// 报表服务数据库
/// </summary>
public partial class RSDbContext:DbContext
{
public RSDbContext(DbContextOptions options) : base(options) {
}
}
}

View File

@ -0,0 +1,17 @@
namespace ReportService.Models.ReportApi
{
/// <summary>
/// 请求数据模型
/// </summary>
public class GetDataData
{
/// <summary>
/// 要请求数据的数据库
/// </summary>
public string DbName { get; set; }
/// <summary>
/// 要执行的查询语句
/// </summary>
public string Sql { get; set; }
}
}

View File

@ -33,7 +33,4 @@
<CopyToOutputDirectory>Never</CopyToOutputDirectory> <CopyToOutputDirectory>Never</CopyToOutputDirectory>
</Content> </Content>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="Database\" />
</ItemGroup>
</Project> </Project>

View File

@ -21,10 +21,9 @@ namespace ReportService
// This method gets called by the runtime. Use this method to add services to the container. // This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services) { public void ConfigureServices(IServiceCollection services) {
var connStr = this.Configuration.GetValue<string>("Database:ReportService"); //注册数据上下文工厂
services.AddDbContext<RSDbContext>(b => { services.AddDbContextFactory("Database");
b.UseSqlServer(connStr);
});
//引入存储过程执行器 //引入存储过程执行器
services.AddFalconSPRunner(); services.AddFalconSPRunner();

View File

@ -8,7 +8,8 @@
}, },
"AllowedHosts": "*", "AllowedHosts": "*",
"Database": { "Database": {
"ReportService": "Server=.\\SQLSERVER2008R2;Database=EASY_HEALTHRECORDS;User ID=sa;Password=111" "ReportService": "Server=.\\SQLSERVER2008R2;Database=EASY_HEALTHRECORDS;User ID=sa;Password=111",
"test": "Server=.\\SQLSERVER2008R2;Database=EASY_HEALTHRECORDS;User ID=sa;Password=111"
}, },
"urls": "http://*:9000;https://*:9001" "urls": "http://*:9000;https://*:9001"
} }

View File

@ -6,6 +6,7 @@ var myjs = {
fileContentUrl: "/api/ReportApi/GetHtml", fileContentUrl: "/api/ReportApi/GetHtml",
reportUrl: "/api/ReportApi/GetPrint", reportUrl: "/api/ReportApi/GetPrint",
getresult: "/api/ReportApi/GetResult", getresult: "/api/ReportApi/GetResult",
getData: "/api/ReportApi/GetData",
GetServerTime: "/api/ReportApi/GetServerTime", GetServerTime: "/api/ReportApi/GetServerTime",
}, },
//定义从对象获取请求参数的方法 //定义从对象获取请求参数的方法
@ -56,6 +57,27 @@ var myjs = {
.then(sc) .then(sc)
.catch(ec); .catch(ec);
}, },
//从数据库获取数据。
getData(dbName, sql, sc, ec) {
if (!ec) {
ec = function (e) {
console.log(e);
alert(e);
};
}
if (!sc) {
sc = function (d) { console.log(d); };
}
var url = this.urls.getData;
var rd = { DbName: dbName, Sql: sql, };
fetch(url, {
method: 'POST',
body: JSON.stringify(rd),
headers: new Headers({
'Content-Type': 'application/json'
})
}).then(res => res.json()).catch(ec).then(sc);
},
//提示消息并记录 //提示消息并记录
showmsg(msg) { showmsg(msg) {
console.log(msg); console.log(msg);