Install "EFCore.BulkExtensions" on EntityFrameworkCore module.
Create a custom repository interface in your Core.Shared module:
public interface ICustomRepository : IRepository where TEntity : class, IEntity
{
int CountAsNoTracking();
int CountAsNoTracking(Expression> predicate);
Task CountAsNoTrackingAsync();
Task CountAsNoTrackingAsync(Expression> predicate);
TEntity FirstOrDefaultAsNoTracking(TPrimaryKey id);
TEntity FirstOrDefaultAsNoTracking(Expression> predicate);
Task FirstOrDefaultAsNoTrackingAsync(TPrimaryKey id);
Task FirstOrDefaultAsNoTrackingAsync(Expression> predicate);
IQueryable GetAllAsNoTracking();
IQueryable GetAllIncludingAsNoTracking(params Expression>[] propertySelectors);
List GetAllListAsNoTracking();
List GetAllListAsNoTracking(Expression> predicate);
Task> GetAllListAsNoTrackingAsync();
Task> GetAllListAsNoTrackingAsync(Expression> predicate);
TEntity GetAsNoTracking(TPrimaryKey id);
Task GetAsNoTrackingAsync(TPrimaryKey id);
TEntity LoadAsNoTracking(TPrimaryKey id);
long LongCountAsNoTracking();
long LongCountAsNoTracking(Expression> predicate);
Task LongCountAsNoTrackingAsync();
Task LongCountAsNoTrackingAsync(Expression> predicate);
T QueryAsNoTracking(Func, T> queryMethod);
TEntity SingleAsNoTracking(Expression> predicate);
Task SingleAsNoTrackingAsync(Expression> predicate);
Task BulkInsert(IList entities);
Task BulkUpdate(IList entities);
Task BulkDelete(IList entities);
}
public interface ICustomRepository : ICustomRepository where TEntity : class, IEntity
{
}
public class CustomRepository : ProjectNameRepositoryBase, ICustomRepository where TEntity : class, IEntity
{
private readonly IDbContextProvider _dbContextProvider;
public CustomRepository(IDbContextProvider dbContextProvider) : base(dbContextProvider)
{
_dbContextProvider = dbContextProvider;
}
public virtual IQueryable GetAllAsNoTracking()
{
return GetAll().AsNoTracking();
}
public virtual IQueryable GetAllIncludingAsNoTracking(params Expression>[] propertySelectors)
{
return GetAllAsNoTracking();
}
public virtual List GetAllListAsNoTracking()
{
return GetAllAsNoTracking().ToList();
}
public virtual Task> GetAllListAsNoTrackingAsync()
{
return Task.FromResult(GetAllListAsNoTracking());
}
public virtual List GetAllListAsNoTracking(Expression> predicate)
{
return GetAllAsNoTracking().Where(predicate).ToList();
}
public virtual Task> GetAllListAsNoTrackingAsync(Expression> predicate)
{
return Task.FromResult(GetAllListAsNoTracking(predicate));
}
public virtual T QueryAsNoTracking(Func, T> queryMethod)
{
return queryMethod(GetAllAsNoTracking());
}
public virtual TEntity GetAsNoTracking(TPrimaryKey id)
{
var entity = FirstOrDefaultAsNoTracking(id);
if (entity == null)
{
throw new EntityNotFoundException(typeof(TEntity), id);
}
return entity;
}
public virtual async Task GetAsNoTrackingAsync(TPrimaryKey id)
{
var entity = await FirstOrDefaultAsNoTrackingAsync(id);
if (entity == null)
{
throw new EntityNotFoundException(typeof(TEntity), id);
}
return entity;
}
public virtual TEntity SingleAsNoTracking(Expression> predicate)
{
return GetAllAsNoTracking().Single(predicate);
}
public virtual Task SingleAsNoTrackingAsync(Expression> predicate)
{
return Task.FromResult(SingleAsNoTracking(predicate));
}
public virtual TEntity FirstOrDefaultAsNoTracking(TPrimaryKey id)
{
return GetAllAsNoTracking().FirstOrDefault(CreateEqualityExpressionForId(id));
}
public virtual Task FirstOrDefaultAsNoTrackingAsync(TPrimaryKey id)
{
return Task.FromResult(FirstOrDefaultAsNoTracking(id));
}
public virtual TEntity FirstOrDefaultAsNoTracking(Expression> predicate)
{
return GetAllAsNoTracking().FirstOrDefault(predicate);
}
public virtual Task FirstOrDefaultAsNoTrackingAsync(Expression> predicate)
{
return Task.FromResult(FirstOrDefaultAsNoTracking(predicate));
}
public virtual TEntity LoadAsNoTracking(TPrimaryKey id)
{
return GetAsNoTracking(id);
}
public virtual int CountAsNoTracking()
{
return GetAllAsNoTracking().Count();
}
public virtual Task CountAsNoTrackingAsync()
{
return Task.FromResult(CountAsNoTracking());
}
public virtual int CountAsNoTracking(Expression> predicate)
{
return GetAllAsNoTracking().Where(predicate).Count();
}
public virtual Task CountAsNoTrackingAsync(Expression> predicate)
{
return Task.FromResult(CountAsNoTracking(predicate));
}
public virtual long LongCountAsNoTracking()
{
return GetAllAsNoTracking().LongCount();
}
public virtual Task LongCountAsNoTrackingAsync()
{
return Task.FromResult(LongCountAsNoTracking());
}
public virtual long LongCountAsNoTracking(Expression> predicate)
{
return GetAllAsNoTracking().Where(predicate).LongCount();
}
public virtual Task LongCountAsNoTrackingAsync(Expression> predicate)
{
return Task.FromResult(LongCountAsNoTracking(predicate));
}
public virtual async Task BulkInsert(IList entities)
{
var _context = await _dbContextProvider.GetDbContextAsync();
var bulkConfig = new BulkConfig { BulkCopyTimeout = 0, BatchSize = 4000 };
_context.Database.SetCommandTimeout(600);
await _context.BulkInsertAsync(entities, bulkConfig);
}
public virtual async Task BulkUpdate(IList entities)
{
var _context = await _dbContextProvider.GetDbContextAsync();
var bulkConfig = new BulkConfig { BulkCopyTimeout = 0, BatchSize = 4000 };
_context.Database.SetCommandTimeout(600);
await _context.BulkUpdateAsync(entities, bulkConfig);
}
public virtual async Task BulkDelete(IList entities)
{
var _context = await _dbContextProvider.GetDbContextAsync();
var bulkConfig = new BulkConfig { BulkCopyTimeout = 0, BatchSize = 4000 };
_context.Database.SetCommandTimeout(600);
await _context.BulkDeleteAsync(entities, bulkConfig);
}
}
Register this repository on PreInitialize (EntityFrameworkCoreModule):
IocManager.IocContainer.Register(Component.For(typeof(ICustomRepository)).ImplementedBy(typeof(CusomRepository)).LifestyleTransient());
Use:
public class TestAppService : ProjectAppServiceBase, ITestAppService
{
private readonly ICustomRepository _carRepository;
public TestAppService(ICustomRepository carRepository)
{
_carRepository = carRepository;
}
public async Task Test(TestInput input)
{
// do a logic
// await _carRepository.BulkInsert(input.cars);
}
}