diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml
index bdd16ff9..da7ace6b 100644
--- a/FreeSql.DbContext/FreeSql.DbContext.xml
+++ b/FreeSql.DbContext/FreeSql.DbContext.xml
@@ -538,14 +538,5 @@
-
-
- 批量注入 Repository,可以参考代码自行调整
-
-
-
-
-
-
diff --git a/FreeSql.Tests/FreeSql.Tests/ClickHouse/ClickHouseTest1.cs b/FreeSql.Tests/FreeSql.Tests/ClickHouse/ClickHouseTest1.cs
index 55133c34..22cece67 100644
--- a/FreeSql.Tests/FreeSql.Tests/ClickHouse/ClickHouseTest1.cs
+++ b/FreeSql.Tests/FreeSql.Tests/ClickHouse/ClickHouseTest1.cs
@@ -3,6 +3,9 @@ using System.Collections.Generic;
using System.Reflection;
using System.Text;
using Xunit;
+using System.Linq;
+using System.Collections;
+using System.Diagnostics;
namespace FreeSql.Tests.MySql
{
@@ -32,13 +35,18 @@ namespace FreeSql.Tests.MySql
public int? Points { get; set; }
}
[FreeSql.DataAnnotations.Table(Name = "ClickHouseTest")]
- public class TestClickHouse
+ public class TestClickHouse : IEnumerable
{
[FreeSql.DataAnnotations.Column(IsPrimary = true)]
[Now]
public long Id { get; set; }
public string Name { get; set; }
+ public IEnumerator GetEnumerator()
+ {
+ yield return Id;
+ yield return Name;
+ }
}
class NowAttribute: Attribute { }
@@ -73,9 +81,10 @@ namespace FreeSql.Tests.MySql
[Fact]
public void TestInsert()
{
+ Stopwatch stopwatch =new Stopwatch();
var fsql = g.clickHouse;
List list=new List();
- for (int i = 0; i < 1000; i++)
+ for (int i = 0; i < 1000000; i++)
{
list.Add(new TestClickHouse()
{
@@ -83,9 +92,13 @@ namespace FreeSql.Tests.MySql
Name = $"测试{i}"
});
}
+ fsql.Delete().Where(t => 1 == 1).ExecuteAffrows();
+ stopwatch.Start();
fsql.Insert(list).ExecuteAffrows();
- var items = fsql.Select().Where(o=>o.Id>900).OrderByDescending(o=>o.Id).ToList();
- Assert.Equal(100, items.Count);
+ stopwatch.Stop();
+ Debug.WriteLine(list.Count+"条用时:" +stopwatch.ElapsedMilliseconds.ToString());
+ //var items = fsql.Select().Where(o=>o.Id>900).OrderByDescending(o=>o.Id).ToList();
+ //Assert.Equal(100, items.Count);
}
[Fact]
diff --git a/Providers/FreeSql.Provider.ClickHouse/Curd/ClickHouseInsert.cs b/Providers/FreeSql.Provider.ClickHouse/Curd/ClickHouseInsert.cs
index 6ddbb87b..57f606bb 100644
--- a/Providers/FreeSql.Provider.ClickHouse/Curd/ClickHouseInsert.cs
+++ b/Providers/FreeSql.Provider.ClickHouse/Curd/ClickHouseInsert.cs
@@ -1,9 +1,12 @@
-using FreeSql.Internal;
+using ClickHouse.Client.ADO;
+using ClickHouse.Client.Copy;
+using FreeSql.Internal;
using FreeSql.Internal.Model;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
+using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -30,9 +33,9 @@ namespace FreeSql.ClickHouse.Curd
internal Dictionary InternalIgnore => _ignore;
internal void InternalClearData() => ClearData();
- public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000);
- public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000);
- public override List ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000);
+ public override int ExecuteAffrows() => base.SplitExecuteAffrows(int.MaxValue, int.MaxValue);
+ public override long ExecuteIdentity() => base.SplitExecuteIdentity(int.MaxValue, int.MaxValue);
+ public override List ExecuteInserted() => base.SplitExecuteInserted(int.MaxValue, int.MaxValue);
public override string ToSql()
@@ -42,6 +45,81 @@ namespace FreeSql.ClickHouse.Curd
return $"INSERT IGNORE INTO {sql.Substring(12)}";
}
+ protected override int RawExecuteAffrows()
+ {
+ var affrows = 0;
+ Exception exception = null;
+ Aop.CurdBeforeEventArgs before=null;
+ if (_source.Count>1)
+ {
+ try
+ {
+ before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, null, _params);
+ _orm.Aop.CurdBeforeHandler?.Invoke(this, before);
+ using var bulkCopyInterface = new ClickHouseBulkCopy(_orm.Ado.MasterPool.Get().Value as ClickHouseConnection)
+ {
+ DestinationTableName = _table.DbName,
+ BatchSize = _source.Count
+ };
+ bulkCopyInterface.WriteToServerAsync(ToDataTable(),default).Wait();
+ return affrows;
+ }
+ catch (Exception ex)
+ {
+ exception = ex;
+ throw ex;
+ }
+ finally
+ {
+ var after = new Aop.CurdAfterEventArgs(before, exception, affrows);
+ _orm.Aop.CurdAfterHandler?.Invoke(this, after);
+ }
+ }
+ else
+ {
+ var sql = this.ToSql();
+ before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params);
+ _orm.Aop.CurdBeforeHandler?.Invoke(this, before);
+ try
+ {
+ affrows = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params);
+ }
+ catch (Exception ex)
+ {
+ exception = ex;
+ throw ex;
+ }
+ finally
+ {
+ var after = new Aop.CurdAfterEventArgs(before, exception, affrows);
+ _orm.Aop.CurdAfterHandler?.Invoke(this, after);
+ }
+ return affrows;
+ }
+ }
+
+ private IDictionary GetValue(T u, System.Reflection.PropertyInfo[] columns)
+ {
+ try
+ {
+ Dictionary dic = new Dictionary();
+ foreach (var item in columns)
+ {
+ object v = null;
+ if (u != null)
+ {
+ v = item.GetValue(u);
+ }
+ dic.TryAdd(item.Name, v);
+ }
+ return dic;
+ }
+ catch (Exception e)
+ {
+ throw;
+ }
+ }
+
protected override long RawExecuteIdentity()
{
var sql = this.ToSql();
diff --git a/Providers/FreeSql.Provider.ClickHouse/Curd/ClickHouseUpdate.cs b/Providers/FreeSql.Provider.ClickHouse/Curd/ClickHouseUpdate.cs
index a284c98d..16745836 100644
--- a/Providers/FreeSql.Provider.ClickHouse/Curd/ClickHouseUpdate.cs
+++ b/Providers/FreeSql.Provider.ClickHouse/Curd/ClickHouseUpdate.cs
@@ -24,7 +24,11 @@ namespace FreeSql.ClickHouse.Curd
internal Dictionary InternalIgnore => _ignore;
public override string ToSql()
{
- return base.ToSql()?.Replace("UPDATE", "ALTER TABLE").Replace("SET", "UPDATE");
+ var sql = base.ToSql();
+ sql = sql.Remove(0, 6).Insert(0, "ALTER TABLE");
+ var index = sql.IndexOf(" SET ");
+ sql = sql.Remove(index, 5).Insert(index, " UPDATE ");
+ return sql;
}
internal void InternalResetSource(List source) => _source = source;
internal string InternalWhereCaseSource(string CsName, Func thenValue) => WhereCaseSource(CsName, thenValue);