C# EF Core Savechanges不适用于删除
我正在尝试从域中删除子项,但Savechanges()不起作用,并且没有发生异常,我正在跟踪并在Dbcontext中找到状态更改为modified的实体。添加或更新工作正常。在我添加IEventbus接口发布事件之前,一切正常。在域类中删除我的方法C# EF Core Savechanges不适用于删除,c#,entity-framework,entity-framework-core,domain-driven-design,savechanges,C#,Entity Framework,Entity Framework Core,Domain Driven Design,Savechanges,我正在尝试从域中删除子项,但Savechanges()不起作用,并且没有发生异常,我正在跟踪并在Dbcontext中找到状态更改为modified的实体。添加或更新工作正常。在我添加IEventbus接口发布事件之前,一切正常。在域类中删除我的方法 public void RemoveItem(Guid id, IEventBus eventBus) { if (!string.IsNullOrWhiteSpace(this.Confirmer.UserId))
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));
}
这是我保存在数据库中的工作单元
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);
}
}
对该删除的操作在其他域中有效,即使在父实体中也是如此,但在这种情况下,不会在数据库中删除。ChangeTracker显示特定的实体状态更改为“已修改”,但毫无例外地完成作业,并且不会对数据库产生影响
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);
}
}
我有一个装饰设计模式的应用服务层来调用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);
}
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;
}
}
}
公共无效调度(TCommand命令)
其中TCommand:Command
{
var commandHandler=this.diContainer.Resolve();
var transactionCommandHandler=新transactionCommandHandler(commandHandler,this.diContainer);
var logCommandHandler=新的logCommandHandler(transactionCommandHandler);
执行(命令);
}
和调用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);
}
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;
}
}
}
公共类TransactionalCommandHandler:ICommandHandler
其中TCommand:Command
{
私有只读ICommandHandler命令处理程序;
私有只读IDI容器;
公共TransactionalCommandHandler(ICommandHandler commandHandler,IDiContainer容器)
{
this.commandHandler=commandHandler;
this.container=容器;
}
public void Execute(TCommand命令)
{
var unitOfWork=this.container.Resolve();//ServiceLocator.Current.Resolve();
尝试
{
this.commandHandler.Execute(命令);
unitOfWork.Commit();
}
捕获(例外e)
{
unitOfWork.RollBack();
投掷;
}
}
}
从集合中删除实体只会将其状态标记为已删除。
您需要调用SaveChanges方法来反映对数据库的更改。一个非常简单的疏忽导致了这个问题。
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);
}
}
在我的命令facade中,有忘记放置“scope.complete()”的事务作用域
public void deleteSparpItem(deleteSparpItemCommand命令)
{
使用(var scope=new TransactionScope())
{
Action updateasetstatus=p=>this.CommandBus.Dispatch(新的updateasetstatuscommand()
{
AssetId=p.AssetId,
状态=0
});
this.eventBus.Subscribe(updateAssetStatus);
此.CommandBus.Dispatch(命令);
scope.Complete();//忘记将此。。。
}
}
这是如何解决问题的?一点解释确实可以改进您的答案。这是一种(域驱动设计)方法,使用Dispatcher自动调用UnitOfWork并提交(再次查看问题,问题已更新)。。。而且UnitOfwork和my domain中的commit是不知道持久性的,所以应该将IEventBus注入构造函数中,而不是方法本身。可能它违反了命令模式,DI不能猜测直接调用该方法。在调用RemoveItem后,检查实体状态是否有任何更改?