EF Core之批量操作(EFCore.BulkExtensions)
EFCore的批量操作性能也在不斷完善當中,但還是不夠優秀,數據量大的情況下還是要單獨處理,這里我們使用EFCore.BulkExtensions(SqlServer)
-
查詢
EFCore.BulkExtensions的批量查詢還是不適合開箱即用,需要做一些基礎封裝,我們可以在Context里增加擴展方法
public async Task<List<T>> WhereInAsync<T>(List<T> data, string column) where T : class { return await MultiWhereInAsync(data, new List<string>() { column }); }
public async Task<List<T>> MultiWhereInAsync<T>(List<T> data, List<string> column) where T : class { var bulkReadConfig = new BulkConfig { UpdateByProperties = column }; return await MyBulkReadAsync(data, bulkReadConfig); }
public static List<T> FilterIn<T>(this IList<T> entities) where T : class { var result = entities?.ToList() ?? new List<T>(); if (!result.IsNullOrEmpty()) { //這里通過主鍵過濾掉不存在的數據 var filterExpression = LambdaUtil.GetExpression<T>("Id", "0", LambdaUtil.ConditionType.GreaterThan); if (filterExpression != null) { result = entities.AsQueryable().Where(filterExpression).ToList(); } } return result; }
public async Task<List<T>> MyBulkReadAsync<T>( IList<T> entities, BulkConfig bulkConfig = null, Action<Decimal> progress = null, CancellationToken cancellationToken = default) where T : class { var result = entities?.ToList() ?? new List<T>(); try { //由於存在bug,entities必須去重 await this.BulkReadAsync(entities, bulkConfig, progress, cancellationToken); //篩選去掉不存在的 result = entities.FilterIn(); } catch (SqlException e) { HandleSqlException(e); } return result; }
-
查詢使用
//whereIns數據量過大時,直接使用EFCore的Contains方法會導致sql過長,無法使用,除了使用原生sql,我們還可以封裝WhereIn方法 var result = await _dbContext.WhereInAsync(whereIns, nameof(Model.Field));
-
新增更新
新增和更新可以做到開箱即用,我們可以在Context里增加擴展方法
public async Task MyBulkInsertAsync<T>( IList<T> entities, BulkConfig bulkConfig = null, Action<Decimal> progress = null, CancellationToken cancellationToken = default) where T : class { try { await this.BulkInsertAsync(entities, bulkConfig, progress, cancellationToken); } catch (SqlException e) { HandleSqlException(e); } } public async Task MyBulkUpdateAsync<T>( IList<T> entities, BulkConfig bulkConfig = null, Action<Decimal> progress = null, CancellationToken cancellationToken = default) where T : class { try { await this.BulkUpdateAsync(entities, bulkConfig, progress, cancellationToken); } catch (SqlException e) { HandleSqlException(e); } }