Entity Framework Core 8: обновление дочерних сущностейC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Entity Framework Core 8: обновление дочерних сущностей

Сообщение Anonymous »

Я пытаюсь обновить дочерний объект, но получаю исключение DbUpdateConcurrencyException при вызове SaveChanges. Моя организация (родительская) имеет список устройств (дочерних). Планировалось собрать организацию, добавить в нее новое устройство, а затем обновить базу данных.
Заранее спасибо.
Я с использованием Entity Framework Core 8.0.10.
Вот моя функция Handle:

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

public async Task Handle(CreateDeviceCommand command, CancellationToken cancellationToken)
{
var organisation = await _organisationRepository.GetAsync(command.OrganisationId);

if (organisation == null)
return Result.Failure(CreateDeviceErrors.NullOrganisation);

var deviceResult = Device.Create(organisation, command.DeviceId, command.DeviceName);

if (deviceResult.IsFailure)
return Result.Failure(deviceResult.Error);

var addDeviceResult = organisation.AddDevice(deviceResult.Value);

if (addDeviceResult.IsFailure)
return Result.Failure(addDeviceResult.Error);

_organisationRepository.Update(organisation);

await _unitOfWork.SaveChangesAsync(cancellationToken);

return Result.Success();
}
Класс «Моя организация»:

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

public sealed class Organisation : Entity
{
public string Name { get; private set; }
public DateTimeOffset Created { get; private set; }
public DateTimeOffset Updated { get; private set; }
public bool Deleted { get; private set; }
public List Devices { get; private set; }

public Result AddDevice(Device device)
{
if (Devices.Any(d => d.ExternalDeviceId == device.ExternalDeviceId))
return Result.Failure(OrganisationErrors.DuplicateDevice);

Devices.Add(device);

return Result.Success();
}
}
И класс моего устройства:

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

public sealed class Device : Entity
{
public string ExternalDeviceId { get; private set; }
public string Name { get; private set; }
public Guid OrganisationId { get; private set; }
public DateTimeOffset Created { get; private set; }
public DateTimeOffset Updated { get; private set; }
public bool Deleted { get; private set; }
}
Это метод обновления в моем репозитории организации:

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

public void Update(Organisation organisation)
{
_context.Organisations.Update(organisation);
}
И полная ошибка:

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

Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException : The database operation was expected to affect 1 row(s), but actually affected 0 row(s); data may have been modified or deleted since entities were loaded.  See https://go.microsoft.com/fwlink/?LinkId=527962 for information on understanding and handling optimistic concurrency exceptions.
at Npgsql.EntityFrameworkCore.PostgreSQL.Update.Internal.NpgsqlModificationCommandBatch.ThrowAggregateUpdateConcurrencyExceptionAsync(RelationalDataReader reader, Int32 commandIndex, Int32 expectedRowsAffected, Int32 rowsAffected, CancellationToken cancellationToken)
at Npgsql.EntityFrameworkCore.PostgreSQL.Update.Internal.NpgsqlModificationCommandBatch.Consume(RelationalDataReader reader, Boolean async, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(IList`1 entriesToSave, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(StateManager stateManager, Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
at Rubicon.Licensing.Infrastructure.LicensingContext.SaveChangesAsync(CancellationToken cancellationToken) in C:\_repos\Rubicon.Platform.Payment\src\Licensing\Rubicon.Licensing.Infrastructure\LicensingContext.cs:line 49
at Rubicon.Licensing.Application.Devices.Create.CreateDeviceHandler.Handle(CreateDeviceCommand command, CancellationToken cancellationToken) in C:\_repos\Rubicon.Platform.Payment\src\Licensing\Rubicon.Licensing.Application\Devices\Create\CreateDeviceHandler.cs:line 39
at Rubicon.Licensing.Database.Tests.IntegrationTests.CreateDevice() in C:\_repos\Rubicon.Platform.Payment\Rubicon.Licensing.Database.Tests\IntegrationTests.cs:line 101
at NUnit.Framework.Internal.TaskAwaitAdapter.GenericAdapter`1.BlockUntilCompleted()
at NUnit.Framework.Internal.MessagePumpStrategy.NoMessagePumpStrategy.WaitForCompletion(AwaitAdapter awaiter)
at NUnit.Framework.Internal.AsyncToSyncAdapter.Await(Func`1 invoke)
at NUnit.Framework.Internal.Commands.TestMethodCommand.RunTestMethod(TestExecutionContext context)
at NUnit.Framework.Internal.Commands.TestMethodCommand.Execute(TestExecutionContext context)
at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand.c__DisplayClass1_0.b__0()
at NUnit.Framework.Internal.Commands.DelegatingTestCommand.RunTestMethodInThreadAbortSafeZone(TestExecutionContext context, Action action)

info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (466ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE DATABASE "Licensing";
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (27ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE "Organisations" (
"Id" uuid NOT NULL,
"Name" text NOT NULL,
"Created" timestamp with time zone NOT NULL,
"Updated" timestamp with time zone NOT NULL,
"Deleted" boolean NOT NULL,
CONSTRAINT "PK_Organisations" PRIMARY KEY ("Id")
);
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (9ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE "Users" (
"Id" uuid NOT NULL,
"AuthenticationId" text NOT NULL,
"Email" text NOT NULL,
"Name" text NOT NULL,
"Created" timestamp with time zone NOT NULL,
"Updated"  timestamp with time zone NOT NULL,
"Deleted" boolean NOT NULL,
CONSTRAINT "PK_Users" PRIMARY KEY ("Id")
);
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (13ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE "Subscriptions" (
"Id" uuid NOT NULL,
"UserId" uuid NOT NULL,
"Source" integer NOT NULL,
"Status" integer NOT NULL,
"Created" timestamp with time zone NOT NULL,
"Updated" timestamp with time zone NOT NULL,
CONSTRAINT "PK_Subscriptions" PRIMARY KEY ("Id"),
CONSTRAINT "FK_Subscriptions_Users_UserId" FOREIGN KEY ("UserId") REFERENCES "Users" ("Id") ON DELETE CASCADE
);
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (5ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE "Licenses" (
"Id" uuid NOT NULL,
"SubscriptionId" uuid NOT NULL,
"ProductType" integer NOT NULL,
"Quantity" integer NOT NULL,
CONSTRAINT "PK_Licenses" PRIMARY KEY ("Id"),
CONSTRAINT "FK_Licenses_Subscriptions_SubscriptionId" FOREIGN KEY ("SubscriptionId") REFERENCES "Subscriptions" ("Id") ON DELETE CASCADE
);
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (5ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE "DeviceLicenses" (
"Id" uuid NOT NULL,
"OrganisationId" uuid NOT NULL,
"LicenseId" uuid NOT NULL,
"Quantity" integer NOT NULL,
"Created" timestamp with time zone NOT NULL,
"Updated" timestamp with time zone NOT NULL,
CONSTRAINT "PK_DeviceLicenses" PRIMARY KEY ("Id"),
CONSTRAINT "FK_DeviceLicenses_Licenses_LicenseId" FOREIGN KEY ("LicenseId") REFERENCES "Licenses" ("Id") ON DELETE CASCADE,
CONSTRAINT "FK_DeviceLicenses_Organisations_OrganisationId" FOREIGN KEY ("OrganisationId") REFERENCES "Organisations" ("Id") ON DELETE CASCADE
);
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (6ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE "PlatformLicenses" (
"Id" uuid NOT NULL,
"OrganisationId" uuid NOT NULL,
"LicenseId" uuid NOT NULL,
"Created" timestamp with time zone NOT NULL,
"Updated" timestamp with time zone NOT NULL,
CONSTRAINT "PK_PlatformLicenses" PRIMARY KEY ("Id"),
CONSTRAINT "FK_PlatformLicenses_Licenses_LicenseId" FOREIGN KEY ("LicenseId") REFERENCES "Licenses" ("Id") ON DELETE CASCADE,
CONSTRAINT "FK_PlatformLicenses_Organisations_OrganisationId" FOREIGN KEY ("OrganisationId") REFERENCES "Organisations" ("Id") ON DELETE CASCADE
);
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (11ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE "Devices" (
"Id" uuid NOT NULL,
"ExternalDeviceId" text NOT NULL,
"Name" text NOT NULL,
"OrganisationId" uuid NOT NULL,
"Created" timestamp with time zone NOT NULL,
"Updated" timestamp with time zone NOT NULL,
"Deleted" boolean NOT NULL,
"DeviceLicenseId" uuid,
CONSTRAINT "PK_Devices" PRIMARY KEY ("Id"),
CONSTRAINT "FK_Devices_DeviceLicenses_DeviceLicenseId" FOREIGN KEY ("DeviceLicenseId") REFERENCES "DeviceLicenses" ("Id"),
CONSTRAINT "FK_Devices_Organisations_OrganisationId" FOREIGN KEY ("OrganisationId") REFERENCES "Organisations"  ("Id") ON DELETE CASCADE
);
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (4ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE INDEX "IX_DeviceLicenses_LicenseId" ON "DeviceLicenses" ("LicenseId");
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (6ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE INDEX "IX_DeviceLicenses_OrganisationId" ON "DeviceLicenses" ("OrganisationId");
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (3ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE INDEX "IX_Devices_DeviceLicenseId" ON "Devices" ("DeviceLicenseId");
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (3ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE INDEX "IX_Devices_OrganisationId" ON "Devices" ("OrganisationId");
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (3ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE INDEX "IX_Licenses_SubscriptionId" ON "Licenses" ("SubscriptionId");
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (4ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE INDEX "IX_PlatformLicenses_LicenseId" ON "PlatformLicenses" ("LicenseId");
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (3ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE UNIQUE INDEX "IX_PlatformLicenses_OrganisationId" ON "PlatformLicenses" ("OrganisationId");
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (3ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE INDEX "IX_Subscriptions_UserId" ON "Subscriptions" ("UserId");
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (26ms) [Parameters=[@__get_Item_0='?' (DbType = Guid)], CommandType='Text', CommandTimeout='30']
SELECT o."Id", o."Created", o."Deleted", o."Name", o."Updated"
FROM "Organisations" AS o
WHERE o."Id" = @__get_Item_0
LIMIT 1
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (7ms) [Parameters=[@p0='?' (DbType = Guid), @p1='?' (DbType = DateTime), @p2='?' (DbType = Boolean), @p3='?', @p4='?' (DbType = DateTime)], CommandType='Text', CommandTimeout='30']
INSERT INTO "Organisations" ("Id", "Created", "Deleted", "Name", "Updated")
VALUES (@p0, @p1, @p2, @p3, @p4);
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (4ms) [Parameters=[@p6='?' (DbType = Guid), @p0='?' (DbType = DateTime), @p1='?' (DbType = Boolean), @p2='?', @p3='?', @p4='?' (DbType = Guid), @p5='?' (DbType = DateTime), @p11='?' (DbType = Guid), @p7='?' (DbType = DateTime), @p8='?' (DbType = Boolean), @p9='?', @p10='?' (DbType = DateTime)], CommandType='Text', CommandTimeout='30']
UPDATE "Devices" SET "Created" = @p0, "Deleted" = @p1, "ExternalDeviceId" = @p2, "Name" = @p3, "OrganisationId" = @p4, "Updated" = @p5
WHERE "Id" = @p6;
UPDATE "Organisations" SET "Created" = @p7, "Deleted" = @p8, "Name" = @p9, "Updated" = @p10
WHERE "Id" = @p11;
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (18ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
DROP DATABASE "Licensing" WITH (FORCE);
Я не уверен, что здесь нужно изменить, я хорошо погуглил и немного застрял. Я могу выполнить рефакторинг обработчика для создания устройства с помощью DeviceRepository, который я протестировал и который работает нормально, но я использую этот шаблон в другом месте и хочу убедиться, что не делаю чего-то глупого.
Есть ли у кого-нибудь идеи?

Подробнее здесь: https://stackoverflow.com/questions/791 ... d-entities
Реклама
Ответить Пред. темаСлед. тема

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

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

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

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

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Entity Framework Core 8: обновление дочерних сущностей
    Anonymous » » в форуме C#
    0 Ответы
    18 Просмотры
    Последнее сообщение Anonymous
  • Entity Framework: обновление дочерних сущностей
    Anonymous » » в форуме C#
    0 Ответы
    9 Просмотры
    Последнее сообщение Anonymous
  • Entity Framework: обновление дочерних сущностей
    Anonymous » » в форуме C#
    0 Ответы
    5 Просмотры
    Последнее сообщение Anonymous
  • Entity Framework Core: проблема при динамическом обновлении сущностей с помощью построителя моделей.
    Anonymous » » в форуме C#
    0 Ответы
    37 Просмотры
    Последнее сообщение Anonymous
  • Entity Framework Core 8 — сопоставление двух сущностей с одной и той же таблицей с помощью разных фильтров (PostgreSQL)
    Anonymous » » в форуме C#
    0 Ответы
    12 Просмотры
    Последнее сообщение Anonymous

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