AddRange/SaveChanges не добавляет данные в БДC#

Место общения программистов C#
Ответить
Anonymous
 AddRange/SaveChanges не добавляет данные в БД

Сообщение Anonymous »

Итак, моя текущая задача — преобразовать огромную древовидную структуру в простую таблицу (которую я только что создал и она пуста), где каждый узел имеет родительский идентификатор, а каждый узел имеет общий идентификатор предка (если узел имеет type_id и присутствует в другой таблице БД, то этот узел является предком, и каждый следующий узел должен иметь его идентификатор в качестве идентификатора подразделения). Древовидная структура представляет собой иерархическую структуру компании размером около 8 МБ и поступает из службы REST с вызовом функции var root = await GetOrganizationStructureByBIN(unid);.
Сначала я хочу показать, как это происходит. сервис и контекст базы данных настроены:
Сервис:

Код: Выделить всё

services.AddTransient();
БД:

Код: Выделить всё

.AddDbContext(options => options.UseNpgsql(mainDbConn ?? configuration.GetConnectionString("DbContextPostgreSql")));
DI dbcontext в службе:

Код: Выделить всё

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)]
Иногда регистрировалось, что DBContext уже удален или что-то в этом роде. А иногда он даже не регистрирует никаких ошибок, вроде бы все идет хорошо и возвращает статус 200, но данные не добавляются в таблицу и она все еще пуста.

Подробнее здесь: https://stackoverflow.com/questions/792 ... data-to-db
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»