Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EF Core Can't Delete a FullAuditedAggregateRoot Entity with ValueObject(Owned Type) #2365

Closed
yinchang0626 opened this issue Dec 10, 2019 · 4 comments

Comments

@yinchang0626
Copy link
Contributor

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.

@hikalkan hikalkan added this to the 1.2 milestone Dec 10, 2019
@hikalkan
Copy link
Member

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

@maliming
Copy link
Member

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

@maliming maliming removed this from the 1.2 milestone Dec 11, 2019
@yinchang0626
Copy link
Contributor Author

@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.

@maliming
Copy link
Member

dotnet/efcore#16186

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants