Сначала я хочу показать, как это происходит. сервис и контекст базы данных настроены:
Сервис:
Код: Выделить всё
services.AddTransient();Код: Выделить всё
.AddDbContext(options => options.UseNpgsql(mainDbConn ?? configuration.GetConnectionString("DbContextPostgreSql")));Код: Выделить всё
private readonly DbContextPostgreSql _db;
public DirectoryService(DbContextPostgreSql db)
{
_db = db;
}
Код: Выделить всё
public async Task UpdateDatabaseDepartmentsLinkedLotus(string unid)
{
if (_db.Database.GetDbConnection().State != ConnectionState.Open)
{
_logger.LogWarning("Database connection is not open. Reopening connection.");
await _db.Database.OpenConnectionAsync();
}
List organizationsLinkedLotus;
try
{
organizationsLinkedLotus = await GetOrganizationsLinkedLotus();
} catch(Exception e)
{
throw new Exception($"CAN'T GET ORGANIZATIONSLINKEDLOTUS ->{e.Message}");
}
_logger.LogInformation($"Total organizations: {organizationsLinkedLotus.Count}");
foreach (var org in organizationsLinkedLotus)
{
_logger.LogInformation($"Organization: {org.Name}, ID: {org.Id}");
}
var organizationsMap = new Dictionary(organizationsLinkedLotus.Count);
var processedDepartmentsList = new List();
for(int i = 0; i < organizationsLinkedLotus.Count; i++)
{
var curr = organizationsLinkedLotus[i];
organizationsMap[curr.Id] = i;
}
var root = await GetOrganizationStructureByBIN(unid);
_logger.LogInformation($"organizationsMap as string -> -> -> {organizationsMap[root.UNID]}");
var stack = new Stack();
if (organizationsMap.ContainsKey(root.UNID))
{
var orgLinkedLotus = organizationsLinkedLotus[organizationsMap[root.UNID]];
stack.Push((root, root.UNID, root.UNID, orgLinkedLotus.TypeId));
}
else
{
stack.Push((root, root.UNID, "", ""));
}
_logger.LogInformation($"RIGHT BEFORE LOOP {stack.Count}");
while (stack.Count > 0)
{
var (currentNode, parentId, subdivisionId, typeId) = stack.Pop();
_logger.LogInformation($"STARTED THE LOOP UNID{currentNode.UNID} {currentNode.Name.RU}");
if(currentNode.UNID == null)
{
_logger.LogInformation($"COULD NOT GET UNID OF CURRENT NODE {currentNode.Name}");
continue;
}
var departmentEntity = new DepartmentLinkedLotus()
{
DepartmentName = currentNode.Name.RU,
Id = currentNode.UNID,
ParentId = parentId,
SubdivisionId = subdivisionId,
TypeId = typeId
};
processedDepartmentsList.Add(departmentEntity);
_logger.LogInformation($"Entities to save: {_db.ChangeTracker.Entries().Count(e => e.State == EntityState.Added)}");
_db.DepartmentsLinkedLotus.Add( departmentEntity );
string nextTypeId, nextSubdivisionId;
if(organizationsMap.ContainsKey(currentNode.UNID))
{
var nextOrg = organizationsLinkedLotus[organizationsMap[currentNode.UNID]];
nextTypeId = nextOrg.TypeId;
nextSubdivisionId = nextOrg.Id;
} else
{
nextTypeId = typeId;
nextSubdivisionId = subdivisionId;
}
if(currentNode.Department != null)
{
foreach(var child in currentNode.Department)
{
stack.Push((child, currentNode.UNID, subdivisionId, typeId));
}
}
}
_logger.LogInformation($"Processed Departments Count: {processedDepartmentsList.Count}");
await SaveDepartmentsInBatches(processedDepartmentsList);
}
Код: Выделить всё
private async Task SaveDepartmentsInBatches(List departments, int batchSize = 100)
{
for (int i = 0; i < departments.Count; i += batchSize)
{
var batch = departments.Skip(i).Take(batchSize).ToList();
_logger.LogInformation($"current batch exemplair{batch[0].DepartmentName} = type_id {batch[0].TypeId}");
_db.DepartmentsLinkedLotus.AddRange(batch);
try
{
await _db.SaveChangesAsync();
}
catch (Exception ex)
{
_logger.LogError($"Error during SaveChangesAsync: {ex.Message}");
throw;
}
}
}
Код: Выделить всё
2024-11-30 00:04:19.5048|4||||EmployeeHttpClient|INFO|organizationsMap as string -> -> -> 4
2024-11-30 00:04:19.5048|4||||EmployeeHttpClient|INFO|RIGHT BEFORE LOOP 1
2024-11-30 00:04:19.5048|4||||EmployeeHttpClient|INFO|STARTED THE LOOP UNIDA8925F4E89C9541A46257F070017B9F9 ОБЪЕДИНЕНИЕ ДИВИЗИОН СЕТЬ
2024-11-30 00:04:31.6551|10||||EmployeeHttpClient|INFO|EXECUTION STARTED UNID -> -> -> 940241000314
2024-11-30 00:04:31.6959|10||||EmployeeHttpClient|WARN|Database connection is not open. Reopening connection.
2024-11-30 00:04:31.6959|10||||IISHttpServer|ERROR|Connection ID "17365880173341179980", Request ID "8000004e-0002-f100-b63f-84710c7967bb": An unhandled exception was thrown by the application.|System.InvalidOperationException: Can't close, connection is in state Connecting
at Npgsql.NpgsqlConnection.Close(Boolean async)
at Npgsql.NpgsqlConnection.CloseAsync()
at Npgsql.NpgsqlConnection.g__DisposeAsyncCore|109_0()
at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.ResetStateAsync(Boolean disposeDbConnection)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.g__Await|22_0(Int32 i, ValueTask vt, List`1 toDispose)
at Microsoft.EntityFrameworkCore.DbContext.DisposeAsync()
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.g__Await|22_0(Int32 i, ValueTask vt, List`1 toDispose)
at Microsoft.AspNetCore.Http.Features.RequestServicesFeature.g__Awaited|9_0(RequestServicesFeature servicesFeature, ValueTask vt)
at Microsoft.AspNetCore.Server.IIS.Core.IISHttpContext.FireOnCompleted()|[Void Start[TStateMachine](TStateMachine ByRef)] => [Void MoveNext()] => [Void ApplicationError(Microsoft.Extensions.Logging.ILogger, System.String, System.String, System.Exception)]
Подробнее здесь: https://stackoverflow.com/questions/792 ... data-to-db
Мобильная версия