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.