using Aop.Api.Domain; using EFCore.BulkExtensions; using Furion.DatabaseAccessor; using Furion.DatabaseAccessor.Extensions; using MediatR; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FlexJobApi.Core { /// /// 同步数据库 /// public class SyncDatabaseCommandHandler() : IRequestHandler { /// /// 同步数据库 /// /// /// /// public async Task Handle(SyncDatabaseCommand request, CancellationToken cancellationToken) { var count = 0; count += await SyncData(); count += await SyncTreeData(); //count += await SyncData(); //count += await SyncData(); //count += await SyncData(); //count += await SyncData(); //count += await SyncData(); //count += await SyncData(); //count += await SyncData(); //count += await SyncData(); //count += await SyncData(); //count += await SyncData(); count += await SyncTreeData(); count += await SyncData(); count += await SyncData(); count += await SyncData(); count += await SyncData(); //count += await SyncData(); //count += await SyncData(); //count += await SyncData(); return count; } private async Task SyncData() where TEntity : CommonEntity, new() { var count = 0; var repTarget = Db.GetRepository(); var repSource = Db.GetRepository(); var sources = await repSource.AsQueryable().AsNoTracking() .OrderBy(it => it.Sort).ThenBy(it => it.CreatedTime) .ToListAsync(); var targets = await repTarget.AsQueryable().AsNoTracking() .OrderBy(it => it.Sort).ThenBy(it => it.CreatedTime) .ToListAsync(); var adds = sources.Where(s => !targets.Any(t => s.Id == t.Id)).ToList(); if (adds.IsNotNull()) { await repTarget.Context.BulkInsertAsync(adds); count += adds.Count; } var updates = sources.Where(s => targets.Any(t => s.Id == t.Id)).ToList(); if (updates.IsNotNull()) { await repTarget.Context.BulkUpdateAsync(updates); count += updates.Count; } var deletes = targets.Where(s => sources.Any(t => s.Id == t.Id)).ToList(); if (deletes.IsNotNull()) { await repTarget.Context.BulkUpdateAsync(deletes); count += deletes.Count; } return count; } private async Task SyncTreeData() where TEntity : CommonEntity, ITreeData, new() { var count = 0; var repTarget = Db.GetRepository(); var repSource = Db.GetRepository(); var sourceData = await repSource.AsQueryable().AsNoTracking() .OrderBy(it => it.Sort).ThenBy(it => it.CreatedTime) .ToListAsync(); var targetData = await repTarget.AsQueryable().AsNoTracking() .OrderBy(it => it.Sort).ThenBy(it => it.CreatedTime) .ToListAsync(); var sources = new List(); var sourceParents = sourceData.Where(it => it.ParentId == null).ToList(); LoopTreeData(sources, sourceData, sourceParents); var targets = new List(); var targetParents = targetData.Where(it => it.ParentId == null).ToList(); LoopTreeData(targets, targetData, targetParents); var adds = sources.Where(s => !targets.Any(t => s.Id == t.Id)).ToList(); if (adds.IsNotNull()) { await repTarget.Context.BulkInsertAsync(adds); count += adds.Count; } var updates = sources.Where(s => targets.Any(t => s.Id == t.Id)).ToList(); if (updates.IsNotNull()) { await repTarget.Context.BulkUpdateAsync(updates); count += updates.Count; } var deletes = targets.Where(s => sources.Any(t => s.Id == t.Id)).ToList(); if (deletes.IsNotNull()) { await repTarget.Context.BulkUpdateAsync(deletes); count += deletes.Count; } return count; } private void LoopTreeData(List entities, List all, List parents) where TEntity : CommonEntity, ITreeData, new() { if (parents.IsNotNull()) { foreach (var parent in parents) { entities.Add(parent); var children = all.Where(it => it.ParentId == parent.Id).ToList(); LoopTreeData(entities, all, children); } } } } }