Browse Source

使用DbContext(DbContextOptionsBuilder(SqlConnection))脱离ABP代理,混合使用ADO.NET和EFCore,动态分表并配置唯一索引和聚集索引,按季度分表和查询

master
wanggang 1 year ago
parent
commit
e280547e4d
  1. 48
      code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/VmiAppService.cs
  2. 28
      code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/VmiAsyncBalanceService.cs

48
code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/VmiAppService.cs

@ -1,6 +1,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
@ -138,7 +140,7 @@ public class VmiAppService : ApplicationService, IJobService, ITransientDependen
db.Set<VmiSnapshot>().Add(snapshot); db.Set<VmiSnapshot>().Add(snapshot);
db.SaveChanges(); db.SaveChanges();
db.Database.ExecuteSqlRaw($"select * into {table} from Set_VmiBalance;"); db.Database.ExecuteSqlRaw($"select * into {table} from Set_VmiBalance;");
db.Database.ExecuteSqlRaw($"create clustered index IX_{table} on {table} (BillTime)"); db.Database.ExecuteSqlRaw($"create clustered index IX_{table}_BillTime on {table} (BillTime)");
snapshot.End = DateTime.Now; snapshot.End = DateTime.Now;
transaction.Commit(); transaction.Commit();
return Task.CompletedTask; return Task.CompletedTask;
@ -217,31 +219,45 @@ public class VmiAppService : ApplicationService, IJobService, ITransientDependen
var start = DateTime.Parse(input.Filters.FirstOrDefault(o => o.Column == "changedTime" && o.Action == EnumFilterAction.BiggerThanOrEqual).Value); var start = DateTime.Parse(input.Filters.FirstOrDefault(o => o.Column == "changedTime" && o.Action == EnumFilterAction.BiggerThanOrEqual).Value);
var end = DateTime.Parse(input.Filters.FirstOrDefault(o => o.Column == "changedTime" && o.Action == EnumFilterAction.SmallThan).Value); var end = DateTime.Parse(input.Filters.FirstOrDefault(o => o.Column == "changedTime" && o.Action == EnumFilterAction.SmallThan).Value);
var tables = new List<string>(); var tables = new List<string>();
var connectionString = this._serviceProvider.GetRequiredService<IConfiguration>().GetConnectionString("SettleAccountService");
using var connection = new SqlConnection(connectionString);
connection.Open();
using var transaction = connection.BeginTransaction();
try
{
for (var time = start; time <= end; time = time.AddMonths(1)) for (var time = start; time <= end; time = time.AddMonths(1))
{ {
var tableName = $"Set_VmiLog_{time.Year}_{(time.Month - 1) / 3 + 1}"; var tableName = $"Set_VmiLog_{time.Year}_{(time.Month - 1) / 3 + 1}";
if (!tables.Contains(tableName)) if (!tables.Contains(tableName))
{
var command = connection.CreateCommand();
command.Transaction = transaction;
command.CommandText = $"select OBJECT_ID('{tableName}', 'U')";
var result = command.ExecuteScalar().ToString();
if (result != string.Empty)
{ {
tables.Add(tableName); tables.Add(tableName);
} }
} else
//不存在则创建table
tables.ForEach(tableName =>
{ {
using var scope = this._serviceProvider.CreateScope(); Debug.WriteLine($"{tableName}不存在");
var context = scope.ServiceProvider.GetRequiredService<SettleAccountDbContext>(); //以为代码为测试建表建唯一索引和物理索引
using var connection = context.Database.GetDbConnection(); command.CommandText = $"select * into {tableName} from Set_VmiLog where 1=0;";
connection.Open(); command.CommandText += $"create unique index IX_{tableName}_Id on {tableName} (Id);";
var cmd = connection.CreateCommand(); command.CommandText += $"create clustered index IX_{tableName}_ChangedTime on {tableName} (ChangedTime);";
cmd.CommandText = $"select OBJECT_ID('{tableName}', 'U')"; command.ExecuteNonQuery();
var result = cmd.ExecuteScalar().ToString(); }
if (result == string.Empty) }
}
transaction.Commit();
}
catch (Exception ex)
{ {
cmd.CommandText = $"select * into {tableName} from Set_VmiLog;create clustered index IX_{tableName} on {tableName} (BillTime);"; Console.WriteLine(ex.ToString());
cmd.ExecuteNonQuery(); transaction.Rollback();
throw;
} }
});
//生成 union all 的 SQL //生成 union all 的 SQL
var sql = $"select * from {tables.First()}"; var sql = $"select * from {tables.First()}";

28
code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/VmiAsyncBalanceService.cs

@ -1,9 +1,12 @@
using System; using System;
using System.Data.SqlClient;
using System.Linq; using System.Linq;
using System.Linq.Dynamic.Core; using System.Linq.Dynamic.Core;
using System.Text.Json; using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
using Magicodes.ExporterAndImporter.Core.Extension; using Magicodes.ExporterAndImporter.Core.Extension;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Omu.ValueInjecter; using Omu.ValueInjecter;
using Volo.Abp.Application.Services; using Volo.Abp.Application.Services;
@ -27,18 +30,35 @@ public class VmiAsyncBalanceService : ApplicationService, IJobService, ITransien
public async Task Invoke(IServiceProvider serviceProvider) public async Task Invoke(IServiceProvider serviceProvider)
{ {
using var scope = _serviceProvider.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<SettleAccountDbContext>(); var connectionString = serviceProvider.GetRequiredService<IConfiguration>().GetConnectionString("SettleAccountService");
using var transaction = db.Database.BeginTransaction(); using var connection = new SqlConnection(connectionString);
connection.Open();
using var transaction = connection.BeginTransaction();
try try
{ {
var options = new DbContextOptionsBuilder<SettleAccountDbContext>().UseSqlServer(connection).Options;
using var db = new SettleAccountDbContext(options);
var messages = db.Set<VmiMessage>().Where(o => !o.isConsumed).OrderBy(o => o.Number).ToList(); var messages = db.Set<VmiMessage>().Where(o => !o.isConsumed).OrderBy(o => o.Number).ToList();
var repo = db.Set<VmiBalance>(); var repo = db.Set<VmiBalance>();
foreach (var message in messages) foreach (var message in messages)
{ {
var log = JsonSerializer.Deserialize<VmiLog>(message.Message); var log = JsonSerializer.Deserialize<VmiLog>(message.Message);
//插入分表 //插入分表
//var tableName = $"Set_VmiLog_{log.BillTime.Year}_{(time.Month - 1) / 3 + 1}"; var tableName = $"Set_VmiLog_{log.ChangedTime.Year}_{(log.ChangedTime.Month - 1) / 3 + 1}";
var command = connection.CreateCommand();
command.Transaction = transaction;
command.CommandText = $"select OBJECT_ID('{tableName}', 'U')";
var result = command.ExecuteScalar().ToString();
if (result == string.Empty)
{
command.CommandText = $"select * into {tableName} from Set_VmiLog where 1=0;";
command.CommandText += $"create unique index IX_{tableName}_Id on {tableName} (Id);";
command.CommandText += $"create clustered index IX_{tableName}_ChangedTime on {tableName} (ChangedTime);";
command.ExecuteNonQuery();
}
//插入到分表
command.CommandText = $"insert into {tableName} select * from Set_VmiLog where id ='{log.Id}'";
//插入库存 //插入库存
var balance = db.Set<VmiBalance>().FirstOrDefault( var balance = db.Set<VmiBalance>().FirstOrDefault(
o => o.DeliverBillType == log.DeliverBillType && o => o.DeliverBillType == log.DeliverBillType &&

Loading…
Cancel
Save