/// <summary>获取数据抽取器。优先自增,默认分页</summary> /// <param name="table"></param> /// <returns></returns> protected virtual IExtracter <DbTable> GetExtracter(IDataTable table) { // 自增 var id = table.Columns.FirstOrDefault(e => e.Identity); if (id == null) { var pks = table.PrimaryKeys; if (pks != null && pks.Length == 1 && pks[0].DataType.IsInt()) { id = pks[0]; } } var tableName = Dal.Db.FormatName(table); IExtracter <DbTable> extracer; var pk = table.Columns.FirstOrDefault(e => e.PrimaryKey); // 兼容SqlServer2008R2分页功能 if (pk == null || Dal.DbType == DatabaseType.SqlServer) { var dc = table.Columns.FirstOrDefault(); extracer = new PagingExtracter(Dal, tableName, dc.ColumnName); } else { extracer = new PagingExtracter(Dal, tableName); } if (id != null) { extracer = new IdExtracter(Dal, tableName, id.ColumnName); } return(extracer); }
/// <summary>获取数据抽取器。优先自增,默认分页</summary> /// <param name="table"></param> /// <returns></returns> protected virtual IExtracter <DbTable> GetExtracter(IDataTable table) { // 自增 var id = table.Columns.FirstOrDefault(e => e.Identity); if (id == null) { var pks = table.PrimaryKeys; if (pks != null && pks.Length == 1 && pks[0].DataType.IsInt()) { id = pks[0]; } } var tableName = Dal.Db.FormatName(table); IExtracter <DbTable> extracer = new PagingExtracter(Dal, tableName); if (id != null) { extracer = new IdExtracter(Dal, tableName, id.ColumnName); } return(extracer); }
/// <summary>备份单表数据</summary> /// <remarks> /// 最大支持21亿行 /// </remarks> /// <param name="table">数据表</param> /// <param name="stream">目标数据流</param> /// <param name="progress">进度回调,参数为已处理行数和当前页表</param> /// <returns></returns> public Int32 Backup(IDataTable table, Stream stream, Action <Int64, DbTable> progress = null) { var writeFile = new WriteFileActor { Stream = stream, // 最多同时堆积数 BoundedCapacity = 4, }; // 自增 var id = table.Columns.FirstOrDefault(e => e.Identity); if (id == null) { var pks = table.PrimaryKeys; if (pks != null && pks.Length == 1 && pks[0].DataType.IsInt()) { id = pks[0]; } } var tableName = Db.FormatName(table); var sb = new SelectBuilder { Table = tableName }; // 总行数 writeFile.Total = SelectCount(sb); WriteLog("备份[{0}/{1}]开始,共[{2:n0}]行", table, ConnName, writeFile.Total); IExtracter <DbTable> extracer = new PagingExtracter(this, tableName); if (id != null) { extracer = new IdExtracter(this, tableName, id.ColumnName); } var sw = Stopwatch.StartNew(); var total = 0; foreach (var dt in extracer.Fetch()) { var count = dt.Rows.Count; WriteLog("备份[{0}/{1}]数据 {2:n0} + {3:n0}", table, ConnName, extracer.Row, count); if (count == 0) { break; } // 进度报告 progress?.Invoke(extracer.Row, dt); // 消费数据 writeFile.Tell(dt); total += count; } // 通知写入完成 writeFile.Stop(-1); sw.Stop(); var ms = sw.Elapsed.TotalMilliseconds; WriteLog("备份[{0}/{1}]完成,共[{2:n0}]行,耗时{3:n0}ms,速度{4:n0}tps", table, ConnName, total, ms, total * 1000L / ms); // 返回总行数 return(total); }