简体   繁体   中英

EF Core Savechanges not working for Remove

I am trying to remove child item(s) from my domain, but Savechanges() is not working and no exceptions occurred and I am tracing and find my entity in Dbcontext that state changed to modified. add or update working correctly. everything worked ok before I add IEventbus interface to publish an event. my remove method in the domain class.

 public void RemoveItem(Guid id, IEventBus eventBus)
    {
        if (!string.IsNullOrWhiteSpace(this.Confirmer.UserId))
        {
            throw new RemoveItemOfConfirmedScrapException();
        }

        var scrapItem = this.ScrapItems.First(p => p.Id == id);

        var assetId = scrapItem.AssetId;


        this.ScrapItems.Remove(this.ScrapItems.First(p => p.Id == id));


          eventBus.Publish(new ScrapItemRemovedEvent(assetId));
    }

and this is my UnitOfWork for saving in the database.

 public class UnitOfWork : IUnitWork
{
    private readonly IDbContext dbContext;

    private DbContextBase dbContextBase;
    public UnitOfWork(IDbContext dbContext)
    {
        this.dbContext = dbContext;

        this.dbContextBase = dbContext as DbContextBase;
    }

    public void Commit()
    {
        try
        {
            this.dbContext.SaveChanges();
        }
        catch
        {

            RollBack();
            throw;
        }

    }
    public void RollBack()
    {
        this.dbContextBase.ChangeTracker.Entries()
            .Where(e => e.Entity != null).ToList()
            .ForEach(e => e.State = EntityState.Detached);
    }
}

what happens to that delete works in other domains even in parent entity but in this case not delete in database. and ChangeTracker shows that specific entity state changed to "modified" but without any exception finish job and not effected on the database.

I have an application service layer with decoration design pattern to call UnitOfWork

     public void Dispatch<TCommand>(TCommand command)
        where TCommand : Command
    {
        var commandHandler = this.diContainer.Resolve<ICommandHandler<TCommand>>();
        var transactionCommandHandler = new TransactionalCommandHandler<TCommand>(commandHandler, this.diContainer);
        var logCommandHandler = new LogCommandHandler<TCommand>(transactionCommandHandler);
        logCommandHandler.Execute(command);
    }

and transactional class that calls UnitOfWork

    public class TransactionalCommandHandler<TCommand> : ICommandHandler<TCommand>
    where TCommand : Command
{
    private readonly ICommandHandler<TCommand> commandHandler;

    private readonly IDiContainer container;

    public TransactionalCommandHandler(ICommandHandler<TCommand> commandHandler, IDiContainer container)
    {
        this.commandHandler = commandHandler;
        this.container = container;
    }

    public void Execute(TCommand command)
    {
        var unitOfWork = this.container.Resolve<IUnitWork>(); // ServiceLocator.Current.Resolve<IUnitWork>();

        try
        {
            this.commandHandler.Execute(command);
            unitOfWork.Commit();
        }
        catch (Exception e)
        {
           unitOfWork.RollBack();
            throw;
        }


    }
}
    var scrapItem = this.ScrapItems.First(p => p.Id == id);
    var assetId = scrapItem.AssetId;
    this.ScrapItems.Remove(scrapItem);
    this.Commit(); // you weren't committing before

Removing entity from collection only marks it's state as Deleted. You need to call SaveChanges method in order to reflect the changes to database.

A very simple carelessness had caused this problem. in my command facade have transaction scope that forgot put "scope.complete()"

    public void DeleteScrapItem(DeleteScrapItemCommand command)
    {

        using (var scope = new TransactionScope())
        {
            Action<dynamic> updateAssetStatus = p => this.CommandBus.Dispatch(new UpdateAssetStatusCommand()
            {
                AssetId = p.AssetId,
                Status = 0
            });

            this.eventBus.Subscribe<ScrapItemRemovedEvent>(updateAssetStatus);

            this.CommandBus.Dispatch(command);

            scope.Complete(); // forgot put this ...
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM