C# ion,但我想尝试一下,如果它确实存在这样的事情。@Koji不幸的是,没有这样的“等待时间”来配置,锁检测是自动的,并且在非谨慎的时间间隔内发生;当找到锁时,将在同一时刻引发异常。您可能可以尝试ROWLOCK优化器提示,但请注意,在某些情况下,它可能会导致
C# ion,但我想尝试一下,如果它确实存在这样的事情。@Koji不幸的是,没有这样的“等待时间”来配置,锁检测是自动的,并且在非谨慎的时间间隔内发生;当找到锁时,将在同一时刻引发异常。您可能可以尝试ROWLOCK优化器提示,但请注意,在某些情况下,它可能会导致,c#,entity-framework-core,database-deadlocks,C#,Entity Framework Core,Database Deadlocks,ion,但我想尝试一下,如果它确实存在这样的事情。@Koji不幸的是,没有这样的“等待时间”来配置,锁检测是自动的,并且在非谨慎的时间间隔内发生;当找到锁时,将在同一时刻引发异常。您可能可以尝试ROWLOCK优化器提示,但请注意,在某些情况下,它可能会导致性能下降。因此,手动锁在这里看起来是一个很好的解决方案,因为无论从哪一方使用它都无关紧要——C#代码还是数据库,在任何情况下都会使用锁。 public async Task DeleteAndUpsert(List<MyEntity>
ion,但我想尝试一下,如果它确实存在这样的事情。@Koji不幸的是,没有这样的“等待时间”来配置,锁检测是自动的,并且在非谨慎的时间间隔内发生;当找到锁时,将在同一时刻引发异常。您可能可以尝试
ROWLOCK
优化器提示,但请注意,在某些情况下,它可能会导致性能下降。因此,手动锁在这里看起来是一个很好的解决方案,因为无论从哪一方使用它都无关紧要——C#代码还是数据库,在任何情况下都会使用锁。
public async Task DeleteAndUpsert(List<MyEntity> entitiesToDelete, List<MyEntity> entitiesToUpsert)
{
if (entitiesToDelete.Any())
await myRepository.Delete(entitiesToDelete);
if (entitiesToUpsert.Any())
await myRepository.Upsert(entitiesToUpsert);
}
public override async Task Upsert(IList<MyEntity> entities)
{
using (var dbContext = new MyDbContext(DbContextOptions, DbOptions))
{
using (var transaction = dbContext.Database.BeginTransaction())
{
await PurgeDataInChildTables(entities, dbContext);
await dbContext.BulkInsertOrUpdateAsync(entities);
// tables that depends on the parent table (FK_Key)
await dbContext.BulkInsertOrUpdateAsync(entities.SelectMany<Child1>(x => x.Id).ToList());
await dbContext.BulkInsertOrUpdateAsync(entities.SelectMany<Child2>(x => x.Id).ToList());
await dbContext.BulkInsertOrUpdateAsync(entities.SelectMany<Child3>(x => x.Id).ToList());
transaction.Commit();
}
}
}
public override async Task Delete(IList<MyEntity> entities)
{
using (var dbContext = new MyDbContext(DbContextOptions, DbOptions))
{
using (var transaction = dbContext.Database.BeginTransaction())
{
await PurgeDataInChildTables(entities, dbContext);
await dbContext.BulkDeleteAsync(entities);
transaction.Commit();
}
}
}
private async Task PurgeDataInChildTables(IList<MyEntity> entities, MyDbContext dbContext)
{
var ids = entities.Select(x => x.Id).ToList();
await dbContext.Child1.Where(x => ids.Contains(x.Id)).BatchDeleteAsync();
await dbContext.Child2.Where(x => ids.Contains(x.Id)).BatchDeleteAsync();
await dbContext.Child3.Where(x => ids.Contains(x.Id)).BatchDeleteAsync();
}
public override async Task Upsert(IList<MyEntity> entities)
{
using (var dbContext = new MyDbContext(DbContextOptions, DbOptions))
{
await PurgeDataInChildTables(entities, dbContext);
await dbContext.BulkInsertOrUpdateAsync(entities);
// tables that depends on the parent table (FK_Key)
await dbContext.BulkInsertOrUpdateAsync(entities.SelectMany(x => x.Child1).ToList());
await dbContext.BulkInsertOrUpdateAsync(entities.SelectMany(x => x.Child2).ToList());
await dbContext.BulkInsertOrUpdateAsync(entities.SelectMany(x => x.Child3).ToList());
await dbContext.SaveChangesAsync();
}
}
public override async Task Delete(IList<MyEntity> entities)
{
using (var dbContext = new MyDbContext(DbContextOptions, DbOptions))
{
await PurgeDataInChildTables(entities, dbContext);
await dbContext.BulkDeleteAsync(entities);
await dbContext.SaveChangesAsync();
}
}