diff --git a/FeiXian.Client/DataSimulation.cs b/FeiXian.Client/DataSimulation.cs
index af01c7d..56e943f 100644
--- a/FeiXian.Client/DataSimulation.cs
+++ b/FeiXian.Client/DataSimulation.cs
@@ -2,16 +2,22 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
+using System.Linq;
+using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
+using NewLife.Data;
using NewLife.Log;
using NewLife.Model;
+using NewLife.Reflection;
using NewLife.Security;
using XCode;
using XCode.DataAccessLayer;
namespace FeiXian.Client
{
+ delegate String GetBatchSqlDelegate(IDataTable table, IDataColumn[] columns, ICollection<String> updateColumns, ICollection<String> addColumns, IEnumerable<IExtend> list);
+
/// <summary>数据模拟</summary>
public class DataSimulate
{
@@ -48,7 +54,7 @@ namespace FeiXian.Client
var fact = Factory;
var session = fact.Session;
- var pst = fact.Persistence;
+ //var pst = fact.Persistence;
var conn = fact.Table.ConnName;
// 禁用自动关闭连接,避免频繁开关连接影响性能
@@ -58,6 +64,16 @@ namespace FeiXian.Client
// 不必获取自增返回值
fact.AutoIdentity = false;
+ // 使用Sql
+ GetBatchSqlDelegate pst = null;
+ if (UseSql)
+ {
+ var method = session.Dal.Session.GetType().GetMethod("GetBatchSql", BindingFlags.Instance | BindingFlags.NonPublic);
+ if (method == null) throw new InvalidOperationException($"数据库[{session.Dal.DbType}]不支持获取批量Sql");
+
+ pst = method.As<GetBatchSqlDelegate>(session.Dal.Session);
+ }
+
Console.WriteLine();
WriteLog("数据模拟 Count={0:n0} Threads={1} BatchSize={2} UseSql={3} BatchInsert={4}", count, Threads, BatchSize, UseSql, BatchInsert);
@@ -76,9 +92,9 @@ namespace FeiXian.Client
var sw = Stopwatch.StartNew();
Parallel.For(0, cpu, n =>
{
- //WriteLog("正在准备数据[CPU={0}]:", n);
try
{
+ var es = new List<IEntity>();
var k = 0;
for (var i = n; i < count; i += cpu, k++)
{
@@ -96,13 +112,11 @@ namespace FeiXian.Client
else if (item.Type == typeof(DateTime))
e[item.Name] = DateTime.Now.AddSeconds(Rand.Next(-10000, 10000));
}
- var sql = "";
- if (UseSql) sql = pst.GetSql(session, e, DataObjectMethodType.Insert);
- lock (list)
- {
- list.Add(e);
- if (UseSql) qs.Add(sql);
- }
+ es.Add(e);
+ }
+ lock (list)
+ {
+ list.AddRange(es);
}
}
catch (Exception ex)
@@ -110,6 +124,18 @@ namespace FeiXian.Client
XTrace.WriteException(ex);
}
});
+ if (UseSql)
+ {
+ var columns = fact.Fields.Select(e => e.Field).Where(e => !e.Identity).ToArray();
+ for (int i = 0; i < list.Count;)
+ {
+ var es = list.Skip(i).Take(BatchSize).ToList();
+ var sql = pst(session.Table, columns, null, null, es);
+ qs.Add(sql);
+
+ i += es.Count;
+ }
+ }
sw.Stop();
Console.WriteLine();
var ms = sw.Elapsed.TotalMilliseconds;
@@ -121,7 +147,6 @@ namespace FeiXian.Client
try
{
//fact.ConnName = conn + n;
- session.Dal.Db.ShowSQL = false;
fact.FindCount();
}
catch (Exception ex)
@@ -145,39 +170,48 @@ namespace FeiXian.Client
var k = 0;
try
{
- EntityTransaction tr = null;
var dal = session.Dal;
- var es = new List<IEntity>();
-
- for (var i = n; i < list.Count; i += ths, k++)
+ if (UseSql)
{
- if (k % BatchSize == 0)
+ for (var i = n; i < qs.Count; i += ths)
{
- Console.Write(".");
-
- if (UseSql || !BatchInsert)
+ dal.Session.Execute(qs[i]);
+ k += BatchSize;
+ }
+ }
+ else
+ {
+ EntityTransaction tr = null;
+ var es = new List<IEntity>();
+ for (var i = n; i < list.Count; i += ths, k++)
+ {
+ if (k % BatchSize == 0)
{
- tr?.Commit();
- if (useTrans) tr = session.CreateTrans();
+ Console.Write(".");
+
+ if (!BatchInsert)
+ {
+ tr?.Commit();
+ if (useTrans) tr = session.CreateTrans();
+ }
+ else
+ {
+ // 批量插入
+ //es.Insert(true);
+ es.BatchInsert(null, null);
+ es.Clear();
+ }
}
+
+ if (BatchInsert)
+ es.Add(list[i]);
else
- {
- // 批量插入
- //es.Insert(true);
- es.BatchInsert(null, null);
- es.Clear();
- }
+ list[i].Insert();
}
-
- if (UseSql)
- dal.Execute(qs[i]);
- else if (BatchInsert)
- es.Add(list[i]);
- else
- list[i].Insert();
+ tr?.Commit();
+ //es.Insert(true);
+ es.BatchInsert(null, null);
}
- tr?.Commit();
- es.Insert(true);
}
catch (Exception ex)
{