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.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
@ -138,7 +140,7 @@ public class VmiAppService : ApplicationService, IJobService, ITransientDependen
db.Set<VmiSnapshot>().Add(snapshot);
db.SaveChanges();
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;
transaction.Commit();
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 end = DateTime.Parse(input.Filters.FirstOrDefault(o => o.Column == "changedTime" && o.Action == EnumFilterAction.SmallThan).Value);
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))
{
var tableName = $"Set_VmiLog_{time.Year}_{(time.Month - 1) / 3 + 1}";
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);
}
}
//不存在则创建table
tables.ForEach(tableName =>
else
{
using var scope = this._serviceProvider.CreateScope();
var context = scope.ServiceProvider.GetRequiredService<SettleAccountDbContext>();
using var connection = context.Database.GetDbConnection();
connection.Open();
var cmd = connection.CreateCommand();
cmd.CommandText = $"select OBJECT_ID('{tableName}', 'U')";
var result = cmd.ExecuteScalar().ToString();
if (result == string.Empty)
Debug.WriteLine($"{tableName}不存在");
//以为代码为测试建表建唯一索引和物理索引
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();
}
}
}
transaction.Commit();
}
catch (Exception ex)
{
cmd.CommandText = $"select * into {tableName} from Set_VmiLog;create clustered index IX_{tableName} on {tableName} (BillTime);";
cmd.ExecuteNonQuery();
Console.WriteLine(ex.ToString());
transaction.Rollback();
throw;
}
});
//生成 union all 的 SQL
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.Data.SqlClient;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Text.Json;
using System.Threading.Tasks;
using Magicodes.ExporterAndImporter.Core.Extension;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Omu.ValueInjecter;
using Volo.Abp.Application.Services;
@ -27,18 +30,35 @@ public class VmiAsyncBalanceService : ApplicationService, IJobService, ITransien
public async Task Invoke(IServiceProvider serviceProvider)
{
using var scope = _serviceProvider.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<SettleAccountDbContext>();
using var transaction = db.Database.BeginTransaction();
var connectionString = serviceProvider.GetRequiredService<IConfiguration>().GetConnectionString("SettleAccountService");
using var connection = new SqlConnection(connectionString);
connection.Open();
using var transaction = connection.BeginTransaction();
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 repo = db.Set<VmiBalance>();
foreach (var message in messages)
{
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(
o => o.DeliverBillType == log.DeliverBillType &&

Loading…
Cancel
Save