翼度科技»论坛 编程开发 .net 查看内容

使用C# asp.net core 同步数据库

6

主题

6

帖子

18

积分

新手上路

Rank: 1

积分
18
代码片段: 文末附链接。
  1. using DataSync.Core;
  2. using Furion.Logging.Extensions;
  3. using Microsoft.Data.SqlClient;
  4. using Microsoft.Extensions.Logging;
  5. using System.Data;
  6. namespace DataSync.Application.DataSync.Services
  7. {
  8.     public class DataSyncServices : IDataSyncData, ITransient
  9.     {
  10.         private readonly object lockObj = new object();
  11.         /// <summary>
  12.         /// 客户端向服务端同步
  13.         /// </summary>
  14.         /// <param name="clientConn"></param>
  15.         /// <param name="serviceConn">目标数据库</param>
  16.         /// <returns></returns>
  17.         public string SyncDataForClient(string clientConn, string serviceConn)
  18.         {
  19.             return SyncData(clientConn, serviceConn);
  20.         }
  21.         /// <summary>
  22.         /// 服务端向客户端同步
  23.         /// </summary>
  24.         /// <param name="serviceConn"></param>
  25.         /// <param name="clientConn"></param>
  26.         /// <returns></returns>
  27.         public string SyncDataForServer(string serviceConn, string clientConn)
  28.         {
  29.             return SyncData(serviceConn, clientConn);
  30.         }
  31.         /// <summary>
  32.         /// 数据同步
  33.         /// </summary>
  34.         private string SyncData(string sourceConn, string targetConn)
  35.         {
  36.             try
  37.             {
  38.                 //源数据库 数据源链接
  39.                 SqlSugarScope sourceDb = new SqlSugarScope(new ConnectionConfig()
  40.                 {
  41.                     DbType = SqlSugar.DbType.SqlServer,
  42.                     ConnectionString = sourceConn,
  43.                     IsAutoCloseConnection = true,
  44.                     AopEvents = new AopEvents
  45.                     {
  46.                         OnLogExecuting = (sql, ps) =>
  47.                         {
  48. #if DEBUG
  49.                             Log.Information($"语句:{sql},参数:{(ps.Any() ? "[" : string.Empty) + string.Join("|", ps.Select(m => $"{m.ParameterName}={m.Value}")) + (ps.Any() ? "]" : string.Empty)}");
  50. #endif
  51.                         }
  52.                     }
  53.                 });
  54.                 //目标数据库 数据源链接
  55.                 SqlSugarScope targetDb = new SqlSugarScope(new ConnectionConfig()
  56.                 {
  57.                     DbType = SqlSugar.DbType.SqlServer,
  58.                     ConnectionString = targetConn,
  59.                     IsAutoCloseConnection = true,
  60.                     AopEvents = new AopEvents
  61.                     {
  62.                         OnLogExecuting = (sql, ps) =>
  63.                         {
  64. #if DEBUG
  65.                             Log.Information($"语句:{sql},参数:{(ps.Any() ? "[" : string.Empty) + string.Join("|", ps.Select(m => $"{m.ParameterName}={m.Value}")) + (ps.Any() ? "]" : string.Empty)}");
  66. #endif
  67.                         }
  68.                     }
  69.                 });
  70.                 //使用sqlsugar 初始化目标数据库
  71.                 targetDb.DbMaintenance.CreateDatabase();
  72.                 var tableNames = sourceDb.DbMaintenance.GetTableInfoList(false).Select(t => t.Name).ToList(); // 调用函数获取所有表名
  73.                 var syncBlackTable = App.GetConfig<List<string>>("SyncBlackTable");
  74.                 tableNames = tableNames.Except(syncBlackTable).ToList();
  75.                 //多线程
  76.                 Parallel.ForEach(tableNames, tableName =>
  77.                 {
  78.                     lock (lockObj)
  79.                     {
  80.                         // 根据表名从源数据库中获取数据并存入 DataTable
  81.                         var targetdataTable = DataTableHelper.FetchDataFromTable(tableName, sourceDb);
  82.                         //判断数据表在目标库是否存在
  83.                         var flagTargetTab = targetDb.DbMaintenance.IsAnyTable(tableName);
  84.                         if (!flagTargetTab)
  85.                         {
  86.                             // 创建表的SQL语句
  87.                             var createTableSql = $"CREATE TABLE {tableName} (";
  88.                             if (targetdataTable != null && targetdataTable.Rows.Count > 0)
  89.                             {
  90.                                 //目标数据库写入-先移除数据同步标识
  91.                                 DataBaseInfoService.DatatableRemoveCloumns(targetdataTable);
  92.                                 // 遍历DataTable的列
  93.                                 foreach (DataColumn column in targetdataTable.Columns)
  94.                                 {
  95.                                     string columnName = column.ColumnName;
  96.                                     string dataType = DataBaseInfoService.GetSqlDataType(column.DataType);
  97.                                     createTableSql += $"{columnName} {dataType}, ";
  98.                                 }
  99.                                 createTableSql = createTableSql.TrimEnd(',', ' ') + ")";
  100.                                 // 创建表
  101.                                 targetDb.Ado.ExecuteCommand(createTableSql);
  102.                                 ("TargetTable : " + tableName + ",创建成功").LogInformation();
  103.                                 //    }
  104.                                 //}
  105.                             }
  106.                         }
  107.                         //AppSys
  108.                         if (tableName.ToUpper().Equals("APPSYS"))
  109.                         {
  110.                             AppSysDataSync.SyncData(tableName, sourceDb, targetDb);
  111.                         }
  112.                         var selectCountSql = $"SELECT COUNT(*) FROM {tableName} ";
  113.                         var sourceCount = sourceDb.Ado.GetInt(selectCountSql);
  114.                         var middleCount = targetDb.Ado.GetInt(selectCountSql);
  115.                         //增量
  116.                         if (sourceCount > middleCount)
  117.                         {
  118.                             //  commandTarget.Connection = connTarget;
  119.                             // commandTarget.CommandType = CommandType.Text;
  120.                             //查询数据
  121.                             var selectTableSql = $"SELECT * FROM {tableName}";
  122.                             //创建datatable(源数据)
  123.                             var sourceDataTable = sourceDb.Ado.GetDataTable(selectTableSql);
  124.                             if (sourceDataTable != null && sourceDataTable.Rows.Count > 0)
  125.                             {
  126.                                 //新增列 MD5
  127.                                 DataBaseInfoService.DataTableAddColumsMd5(sourceDataTable);
  128.                             }
  129.                             //创建datatable(目标表数据)
  130.                             var targetDataTable = targetDb.Ado.GetDataTable(selectTableSql);
  131.                             if (targetDataTable != null && targetDataTable.Rows.Count > 0)
  132.                             {
  133.                                 //新增列 MD5
  134.                                 DataBaseInfoService.DataTableAddColumsMd5(targetDataTable);
  135.                             }
  136.                             // 计算差集
  137.                             var tempTable = new DataTable();
  138.                             var tempExceptTable = (from source in sourceDataTable.AsEnumerable()
  139.                                                    where
  140.                                                    !(from target in targetDataTable.AsEnumerable() select target.Field<string>("MD5")).Contains(
  141.                                                    source.Field<string>("MD5"))
  142.                                                    select source);
  143.                             if (tempExceptTable != null && tempExceptTable.Count() > 0)
  144.                             {
  145.                                 tempTable = tempExceptTable.CopyToDataTable();
  146.                             }
  147.                             //批量插入数据
  148.                             if (tempTable != null && tempTable.Rows.Count > 0)
  149.                             {
  150.                                 //目标数据库写入-先移除数据同步标识,MD5标识
  151.                                 DataBaseInfoService.DatatableRemoveCloumns(tempTable);
  152.                                 var connTarget = new SqlConnection(targetConn);
  153.                                 DataBaseInfoService.DataBulkCopy(connTarget, tableName, tempTable);
  154.                                 //  TargetDataScope.Db.Fastest<DataTable>().AS(tableName).BulkCopy(tempTable);
  155.                             }
  156.                         }
  157.                         //删除
  158.                         else if (sourceCount < middleCount)
  159.                         {
  160.                             //查询数据
  161.                             var selectTableSql = $"SELECT * FROM {tableName}";
  162.                             //创建datatable(源数据)
  163.                             var sourceDataTable = sourceDb.Ado.GetDataTable(selectTableSql);
  164.                             if (sourceDataTable != null && sourceDataTable.Rows.Count > 0)
  165.                             {
  166.                                 //新增列 MD5
  167.                                 DataBaseInfoService.DataTableAddColumsMd5(sourceDataTable);
  168.                             }
  169.                             //创建datatable
  170.                             var taergetTable = targetDb.Ado.GetDataTable(selectTableSql);
  171.                             if (taergetTable != null && taergetTable.Rows.Count > 0)
  172.                             {
  173.                                 //新增列 MD5
  174.                                 DataBaseInfoService.DataTableAddColumsMd5(taergetTable);
  175.                             }
  176.                             // 计算差集
  177.                             var tempTable = new DataTable();
  178.                             var tempExceptTable = (from target in taergetTable.AsEnumerable()
  179.                                                    where
  180.                                                    !(from source in sourceDataTable.AsEnumerable() select source.Field<string>("MD5")).Contains(
  181.                                                    target.Field<string>("MD5"))
  182.                                                    select target);
  183.                             if (tempExceptTable != null && tempExceptTable.Count() > 0)
  184.                             {
  185.                                 tempTable = tempExceptTable.CopyToDataTable();
  186.                             }
  187.                             if (tempTable != null && tempTable.Rows.Count > 0)
  188.                             {
  189.                                 //获取主键字段
  190.                                 var PrimaryKeyName = targetDb.DbMaintenance.GetPrimaries(tableName);
  191.                                 //DataTableHelper.GetPrimaryKeyFieldName(tableName, connTarget);
  192.                                 //获取自增列
  193.                                 var Identities = targetDb.DbMaintenance.GetIsIdentities(tableName);
  194.                                 if (PrimaryKeyName != null && PrimaryKeyName.Count > 0)
  195.                                 {
  196.                                     foreach (DataRow row in tempTable.Rows)
  197.                                     {
  198.                                         var deleteDataSql = DataTableHelper.ConstructDeleteSql(tableName, PrimaryKeyName, Identities, row);
  199.                                         //$"DELETE FROM {tableName} WHERE {PrimaryKeyName} ='{row[PrimaryKeyName[0]]}'";
  200.                                         //目标数据数据操作对象
  201.                                         targetDb.Ado.ExecuteCommand(deleteDataSql);
  202.                                     }
  203.                                 }
  204.                             }
  205.                         }
  206.                         //更新
  207.                         else
  208.                         {
  209.                             //判断是否存在需要更新的记录
  210.                             //和目标表比较取差集
  211.                             //查询数据
  212.                             var selectTableSql = $"SELECT * FROM {tableName}";
  213.                             //创建datatable(源数据)
  214.                             var sourceDataTable = sourceDb.Ado.GetDataTable(selectTableSql);
  215.                             if (sourceDataTable != null && sourceDataTable.Rows.Count > 0)
  216.                             {
  217.                                 //新增列 MD5
  218.                                 DataBaseInfoService.DataTableAddColumsMd5(sourceDataTable);
  219.                             }
  220.                             //创建datatable(目标表数据)
  221.                             var targetDataTable = targetDb.Ado.GetDataTable(selectTableSql);
  222.                             if (targetDataTable != null && targetDataTable.Rows.Count > 0)
  223.                             {
  224.                                 //新增列 MD5
  225.                                 DataBaseInfoService.DataTableAddColumsMd5(targetDataTable);
  226.                             }
  227.                             // 计算差集
  228.                             var tempTable = new DataTable();
  229.                             var tempExceptTable = (from source in sourceDataTable.AsEnumerable()
  230.                                                    where
  231.                                                    !(from target in targetDataTable.AsEnumerable() select target.Field<string>("MD5")).Contains(
  232.                                                    source.Field<string>("MD5"))
  233.                                                    select source);
  234.                             if (tempExceptTable != null && tempExceptTable.Count() > 0)
  235.                             {
  236.                                 tempTable = tempExceptTable.CopyToDataTable();
  237.                             }
  238.                             if (tempTable != null && tempTable.Rows.Count > 0)
  239.                             {
  240.                                 //删除标识列和MD5列
  241.                                 DataBaseInfoService.DatatableRemoveCloumns(tempTable);
  242.                                 //获取目标表主键字段
  243.                                 var PrimaryKeyName = targetDb.DbMaintenance.GetPrimaries(tableName);
  244.                                 //获取自增列
  245.                                 var Identities = targetDb.DbMaintenance.GetIsIdentities(tableName);
  246.                                 //DataTableHelper.GetPrimaryKeyFieldName(tableName, connTarget);
  247.                                 foreach (DataRow dataRow in tempTable.Rows)
  248.                                 {
  249.                                     var updateDataSql = DataTableHelper.ConstructUpdateSql(tableName, PrimaryKeyName, Identities, dataRow);
  250.                                     targetDb.Ado.ExecuteCommand(updateDataSql);
  251.                                 }
  252.                             }
  253.                         }
  254.                     }
  255.                 });
  256.             }
  257.             catch (Exception ex)
  258.             {
  259.                 ("Error occurred while connecting to database or fetching data from tables.\n" + ex.Message).LogError();
  260.                 return "同步失败。详见错误日志!";
  261.             }
  262.             return "同步完成!";
  263.         }
  264.     }
  265. }
复制代码
  Gitee: https://gitee.com/ltf_free/sync-data.git

来源:https://www.cnblogs.com/100234ltf/p/18001324
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具