Abp: EF Core Can't Delete a FullAuditedAggregateRoot Entity with ValueObject(Owned Type)

Created on 10 Dec 2019  路  4Comments  路  Source: abpframework/abp

When deleting a FullAuditedAggregateRoot Entity with ValueObject(Owned Type).
EntityFrameworkCore will throw an exception:

2019-12-10 19:10:23.047 +08:00 [ERR] An instance of entity type 'ISBN' is marked as 'Deleted', but an instance of entity type 'Book' is marked as 'Modified' and both are mapped to the same row. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the key values.
System.InvalidOperationException: An instance of entity type 'ISBN' is marked as 'Deleted', but an instance of entity type 'Book' is marked as 'Modified' and both are mapped to the same row. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the key values.
   at Microsoft.EntityFrameworkCore.Update.ModificationCommand.AddEntry(IUpdateEntry entry)
   at Microsoft.EntityFrameworkCore.Update.Internal.CommandBatchPreparer.CreateModificationCommands(IList`1 entries, IUpdateAdapter updateAdapter, Func`1 generateParameterName)
   at Microsoft.EntityFrameworkCore.Update.Internal.CommandBatchPreparer.BatchCommands(IList`1 entries, IUpdateAdapter updateAdapter)+MoveNext()
   at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(DbContext _, ValueTuple`2 parameters, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(DbContext _, ValueTuple`2 parameters, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(IList`1 entriesToSave, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
   at Volo.Abp.EntityFrameworkCore.AbpDbContext`1.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken) in C:\Users\YinChang\Documents\Works\Bitbucket\FS\abp\framework\src\Volo.Abp.EntityFrameworkCore\Volo\Abp\EntityFrameworkCore\AbpDbContext.cs:line 149
   at Volo.Abp.Uow.UnitOfWork.SaveChangesAsync(CancellationToken cancellationToken) in C:\Users\YinChang\Documents\Works\Bitbucket\FS\abp\framework\src\Volo.Abp.Uow\Volo\Abp\Uow\UnitOfWork.cs:line 92
   at Volo.Abp.Uow.UnitOfWork.CompleteAsync(CancellationToken cancellationToken) in C:\Users\YinChang\Documents\Works\Bitbucket\FS\abp\framework\src\Volo.Abp.Uow\Volo\Abp\Uow\UnitOfWork.cs:line 143
   at Volo.Abp.AspNetCore.Mvc.Uow.AbpUowActionFilter.OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) in C:\Users\YinChang\Documents\Works\Bitbucket\FS\abp\framework\src\Volo.Abp.AspNetCore.Mvc\Volo\Abp\AspNetCore\Mvc\Uow\AbpUowActionFilter.cs:line 66
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)

I think it should be related to ISoftDelete, because of Book Entity is going to modify IsDeleted to true,but i don't know why Owned Type is set to Deleted by EF

And I modifyed BookStore sample to test it
I hope someone tell me what is wrong,thanks

  1. Change Book Entity to FullAuditedAggregateRoot
    public class Book : FullAuditedAggregateRoot<Guid>
    {
        public string Name { get; set; }

        public BookType Type { get; set; }

        public DateTime PublishDate { get; set; }

        public float Price { get; set; }

        public ISBN ISBN { get; set; }

        protected Book()
        {

        }

        public Book(Guid id, string name, BookType type, DateTime publishDate, float price)
        : base(id)
        {
            Name = name;
            Type = type;
            PublishDate = publishDate;
            Price = price;
        }
    }
  1. Create a ISBN as ValueObject and Book has that
    public class ISBN : Volo.Abp.Domain.Values.ValueObject
    {
        public string EAN { get; set; }
        public string Group { get; set; }
        public string Publisher { get; set; }
        public string Title { get; set; }
        public string CheckDigit { get; set; }

        protected override IEnumerable<object> GetAtomicValues()
        {
            yield return EAN;
            yield return Group;
            yield return Publisher;
            yield return Title;
            yield return CheckDigit;
        }
    }
  1. Configure Book for EntityFrameworkCore
            builder.Entity<Book>(b =>
            {
                b.ToTable(BookStoreConsts.DbTablePrefix + "Books", BookStoreConsts.DbSchema);
                b.ConfigureByConvention();
                b.Property(x => x.Name).IsRequired().HasMaxLength(128);
                b.OwnsOne(x => x.ISBN, y =>
                   {
                       y.Property(y => y.EAN).HasColumnName("EAN");
                       y.Property(y => y.Group).HasColumnName("Group");
                       y.Property(y => y.Publisher).HasColumnName("Publisher");
                       y.Property(y => y.Title).HasColumnName("Title");
                       y.Property(y => y.CheckDigit).HasColumnName("CheckDigit");
                   });

            });
  1. Add ISBNDto for Application
    public class CreateUpdateBookDto
    {
        [Required]
        [StringLength(128)]
        public string Name { get; set; }

        [Required]
        public BookType Type { get; set; } = BookType.Undefined;

        [Required]
        public DateTime PublishDate { get; set; }

        [Required]
        public float Price { get; set; }

        public ISBNDto ISBN { get; set; }

    }

After running database migration,
Add a Book entity success but when i delete it ,will get an above exception.

Most helpful comment

All 4 comments

Thank you for reporting. Will work on this in the next version.

@yinchang0626
ef core 3.1 no longer has this problem, Can you try upgrading ef core 3.1?

@maliming
You are right!!Thank You.But why u know core 3.1 resolved this problem?
After upgrade to 3.1 by merge "maliming/aspnetcore-3.1" branch
and rebuild framework code,this problem is gone.
Now only one thing to do is waitting for abp releases .net core 3.1.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

wocar picture wocar  路  3Comments

hikalkan picture hikalkan  路  3Comments

hikalkan picture hikalkan  路  3Comments

ugurozturk picture ugurozturk  路  3Comments

zsanhong picture zsanhong  路  3Comments