Merge branch 'master' of http://git.newlifex.com/Stone/BigData大石头 authored at 2025-06-22 14:25:50
diff --git a/Big.Data.Web/appsettings.json b/Big.Data.Web/appsettings.json
index 2646ac1..708058b 100644
--- a/Big.Data.Web/appsettings.json
+++ b/Big.Data.Web/appsettings.json
@@ -9,6 +9,6 @@
"AllowedHosts": "*",
//"StarServer": "http://star.newlifex.com:6600",
"ConnectionStrings": {
- "Data": "Data Source=..\\Data\\Data.db;Provider=SQLite"
+ "Data": "Data Source=..\\Data\\Data.db;Cache Size=-524288;Synchronous=Off;Journal Mode=Memory;Provider=SQLite"
}
}
diff --git a/Big.Data.Web/Areas/Data/Controllers/SalesOrderController.cs b/Big.Data.Web/Areas/Data/Controllers/SalesOrderController.cs
index a45d5e7..fd030a4 100644
--- a/Big.Data.Web/Areas/Data/Controllers/SalesOrderController.cs
+++ b/Big.Data.Web/Areas/Data/Controllers/SalesOrderController.cs
@@ -1,24 +1,27 @@
-using NewLife;
+using Big.Data.Web.Services;
+using Microsoft.AspNetCore.Mvc;
+using NewLife;
using NewLife.Cube;
+using NewLife.Log;
+using NewLife.Security;
using NewLife.Web;
+using System.Diagnostics;
+using XCode;
+using XCode.Membership;
namespace Big.Data.Web.Areas.Data.Controllers;
[DataArea]
public class SalesOrderController : EntityController<SalesOrder>
{
- ///// <summary>列表页视图。子控制器可重载,以传递更多信息给视图,比如修改要显示的列</summary>
- ///// <param name="p"></param>
- ///// <returns></returns>
- //protected override ActionResult IndexView(Pager p)
- //{
- // // 禁止非索引字段排序
- // if (!p.Sort.EqualIgnoreCase("", "ID", "Number")) p.Sort = null;
+ private readonly BuildService _buildService;
- // var list = SalesOrder.Search(p["dtStart"].ToDateTime(), p["dtEnd"].ToDateTime(), p["Q"], p);
+ static SalesOrderController()
+ {
+ SalesOrder.Meta.Factory.OrderByKey = true;
+ }
- // return View("List", list);
- //}
+ public SalesOrderController(BuildService buildService) => _buildService = buildService;
protected override IEnumerable<SalesOrder> Search(Pager p)
{
@@ -27,4 +30,46 @@ public class SalesOrderController : EntityController<SalesOrder>
return SalesOrder.Search(p["dtStart"].ToDateTime(), p["dtEnd"].ToDateTime(), p["Q"], p);
}
+
+ [EntityAuthorize(PermissionFlags.Insert)]
+ public ActionResult BuildData()
+ {
+ var task = Task.Run(() =>
+ {
+ // 根据批大小生成100万数据,并插入数据库
+ var batchSize = XCodeSetting.Current.BatchSize;
+ var count = 1_000_000;
+
+ // 管理员放大10倍
+ if (ManageProvider.User.Roles.Any(e => e.IsSystem)) count *= 10;
+
+ _buildService.Build(count, batchSize);
+ });
+
+ // 稍微等待一下,让后台线程有机会执行
+ task.Wait(1000);
+
+ return Json(0, task.IsCompleted ? "完成" : "后台任务正在执行");
+ }
+
+ [EntityAuthorize(PermissionFlags.Insert)]
+ public ActionResult BuildData2()
+ {
+ var task = Task.Run(() =>
+ {
+ // 根据批大小生成100万数据,并插入数据库
+ var batchSize = XCodeSetting.Current.BatchSize;
+ var count = 1_000_000;
+
+ // 管理员放大10倍
+ if (ManageProvider.User.Roles.Any(e => e.IsSystem)) count *= 10;
+
+ _buildService.ActorBuild(count, batchSize);
+ });
+
+ // 稍微等待一下,让后台线程有机会执行
+ task.Wait(1000);
+
+ return Json(0, task.IsCompleted ? "完成" : "后台任务正在执行");
+ }
}
\ No newline at end of file
diff --git a/Big.Data.Web/Areas/Data/Views/SalesOrder/_List_Toolbar_Batch.cshtml b/Big.Data.Web/Areas/Data/Views/SalesOrder/_List_Toolbar_Batch.cshtml
new file mode 100644
index 0000000..7938e6c
--- /dev/null
+++ b/Big.Data.Web/Areas/Data/Views/SalesOrder/_List_Toolbar_Batch.cshtml
@@ -0,0 +1,20 @@
+@using NewLife.Common;
+@using NewLife.Cube
+@using XCode
+@using XCode.Membership
+@{
+ var user = ViewBag.User as IUser ?? User.Identity as IUser;
+ var fact = ViewBag.Factory as IEntityFactory;
+ var set = ViewBag.PageSetting as PageSetting ?? PageSetting.Global;
+}
+@if (set.EnableSelect)
+{
+ <button type="button" class="btn btn-purple btn-sm" data-action="action" data-url="@Url.Action("BuildData")" data-method="post" >
+ <span class="ace-icon fa fa-search icon-on-right bigger-110"></span>
+ 循环生成数据
+ </button>
+ <button type="button" class="btn btn-purple btn-sm" data-action="action" data-url="@Url.Action("BuildData2")" data-method="post" >
+ <span class="ace-icon fa fa-search icon-on-right bigger-110"></span>
+ Actor生成数据
+ </button>
+}
\ No newline at end of file
diff --git a/Big.Data.Web/Big.Data.Web.csproj b/Big.Data.Web/Big.Data.Web.csproj
index ff7839b..2f4e3ac 100644
--- a/Big.Data.Web/Big.Data.Web.csproj
+++ b/Big.Data.Web/Big.Data.Web.csproj
@@ -19,8 +19,8 @@
</PropertyGroup>
<ItemGroup>
- <PackageReference Include="NewLife.Cube.Core" Version="6.2.2024.1212" />
- <PackageReference Include="NewLife.Stardust.Extensions" Version="3.2.2024.1211" />
+ <PackageReference Include="NewLife.Cube.Core" Version="6.3.2025.101" />
+ <PackageReference Include="NewLife.Stardust.Extensions" Version="3.2.2025.101" />
</ItemGroup>
<ItemGroup>
diff --git a/Big.Data.Web/Program.cs b/Big.Data.Web/Program.cs
index f57f571..143fa98 100644
--- a/Big.Data.Web/Program.cs
+++ b/Big.Data.Web/Program.cs
@@ -1,17 +1,24 @@
-using NewLife.Cube;
+using Big.Data.Web.Services;
+using NewLife.Cube;
using NewLife.Log;
+using System.Diagnostics;
//!!! 标准Web项目模板,新生命团队强烈推荐
// 启用控制台日志,拦截所有异常
XTrace.UseConsole();
+//// 提高当前进程优先级,便于生成数据时更快完成
+//Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.AboveNormal;
+
var builder = WebApplication.CreateBuilder(args);
var services = builder.Services;
// 配置星尘。借助StarAgent,或者读取配置文件 config/star.config 中的服务器地址
var star = services.AddStardust(null);
+services.AddSingleton<BuildService>();
+
services.AddControllersWithViews();
services.AddCube();
diff --git a/Big.Data.Web/Services/BuildService.cs b/Big.Data.Web/Services/BuildService.cs
new file mode 100644
index 0000000..71641e6
--- /dev/null
+++ b/Big.Data.Web/Services/BuildService.cs
@@ -0,0 +1,106 @@
+using NewLife.Log;
+using NewLife.Security;
+using System.Diagnostics;
+using XCode.Membership;
+using XCode;
+using NewLife.Model;
+
+namespace Big.Data.Web.Services;
+
+public class BuildService
+{
+ public Int32 Build(Int32 count, Int32 batchSize)
+ {
+ using var _ = SalesOrder.Meta.Session.Dal.Session.SetShowSql(false);
+ var sw = Stopwatch.StartNew();
+
+ var actions = new[] { "入库", "出库", "退回", "调拨", "盘点" };
+
+ var times = count / batchSize;
+ XTrace.WriteLine("准备生成{0:n0}条数据,分{1:n0}批,批大小{2:n0}", count, times, batchSize);
+
+ var rs = 0;
+ for (var i = 0; i < times; i++)
+ {
+ var list = new List<SalesOrder>();
+ for (var j = 0; j < batchSize; j++)
+ {
+ var entity = new SalesOrder
+ {
+ Number = Rand.NextString(16),
+ NodeId = Rand.Next(1, 10000),
+ Action = actions[Rand.Next(actions.Length)],
+ CreateTime = DateTime.Now,
+ };
+ list.Add(entity);
+ }
+ rs += list.Insert();
+ }
+
+ sw.Stop();
+
+ var msg = $"生成{count:n0}条数据,耗时{sw.Elapsed},速度{count * 1000 / sw.ElapsedMilliseconds:n0}tps";
+ XTrace.WriteLine(msg);
+ LogProvider.Provider.WriteLog(typeof(SalesOrder), "BuildData", true, msg);
+
+ return rs;
+ }
+
+ public Int32 ActorBuild(Int32 count, Int32 batchSize)
+ {
+ var sw = Stopwatch.StartNew();
+
+ var actions = new[] { "入库", "出库", "退回", "调拨", "盘点" };
+
+ var times = count / batchSize;
+ XTrace.WriteLine("准备生成{0:n0}条数据,分{1:n0}批,批大小{2:n0}", count, times, batchSize);
+
+ // 并行生成数据,每批送入Actor处理
+ var actor = new BuildActor();
+ Parallel.For(0, times, i =>
+ {
+ var list = new List<SalesOrder>();
+ for (var j = 0; j < batchSize; j++)
+ {
+ var entity = new SalesOrder
+ {
+ Number = Rand.NextString(16),
+ NodeId = Rand.Next(1, 10000),
+ Action = actions[Rand.Next(actions.Length)],
+ CreateTime = DateTime.Now,
+ };
+ list.Add(entity);
+ }
+ actor.Tell(list);
+ });
+ XTrace.WriteLine("数据生成完毕,等待处理");
+
+ actor.Stop(60_000);
+
+ sw.Stop();
+
+ var msg = $"生成{count:n0}条数据,耗时{sw.Elapsed},速度{count * 1000 / sw.ElapsedMilliseconds:n0}tps";
+ XTrace.WriteLine(msg);
+ LogProvider.Provider.WriteLog(typeof(SalesOrder), "BuildData", true, msg);
+
+ return actor.Result;
+ }
+
+ class BuildActor : Actor
+ {
+ public Int32 Result { get; set; }
+
+ private IDisposable _showSql;
+
+ protected override Task ReceiveAsync(ActorContext context, CancellationToken cancellationToken)
+ {
+ // 关闭SQL日志
+ using var _ = SalesOrder.Meta.Session.Dal.Session.SetShowSql(false);
+
+ var list = context.Message as List<SalesOrder>;
+ Result += list.Insert();
+
+ return base.ReceiveAsync(context, cancellationToken);
+ }
+ }
+}
diff --git a/Big.Data/Big.Data.csproj b/Big.Data/Big.Data.csproj
index acacba4..aea4d31 100644
--- a/Big.Data/Big.Data.csproj
+++ b/Big.Data/Big.Data.csproj
@@ -25,8 +25,8 @@
</ItemGroup>
<ItemGroup>
- <PackageReference Include="NewLife.Core" Version="11.1.2024.1206" />
- <PackageReference Include="NewLife.XCode" Version="11.16.2024.1202" />
+ <PackageReference Include="NewLife.Core" Version="11.3.2025.101" />
+ <PackageReference Include="NewLife.XCode" Version="11.17.2025.101" />
</ItemGroup>
</Project>
diff --git a/Big.Data/xcodetool.exe b/Big.Data/xcodetool.exe
index 825192f..f2826c8 100644
Binary files a/Big.Data/xcodetool.exe and b/Big.Data/xcodetool.exe differ