diff --git a/Examples/orm_vs/Program.cs b/Examples/orm_vs/Program.cs new file mode 100644 index 00000000..5c3756e0 --- /dev/null +++ b/Examples/orm_vs/Program.cs @@ -0,0 +1,176 @@ +using FreeSql.DataAnnotations; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; + +namespace orm_vs +{ + class Program + { + static IFreeSql fsql = new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=20") + //.UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=20") + .UseAutoSyncStructure(false) + .UseNoneCommandParameter(true) + //.UseConfigEntityFromDbFirst(true) + .Build(); + + static SqlSugarClient sugar { + get => new SqlSugarClient(new ConnectionConfig() { + //不欺负,让连接池100个最小 + ConnectionString = "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=20;Max Pool Size=20", + DbType = DbType.SqlServer, + //ConnectionString = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=20;Max Pool Size=20", + //DbType = DbType.MySql, + IsAutoCloseConnection = true, + InitKeyType = InitKeyType.Attribute + }); + } + + static StringBuilder sb = new StringBuilder(); + + static void Main(string[] args) { + + //fsql.CodeFirst.SyncStructure(typeof(Song), typeof(Song_tag), typeof(Tag)); + //sugar.CodeFirst.InitTables(typeof(Song), typeof(Song_tag), typeof(Tag)); + //sugar创建表失败:SqlSugar.SqlSugarException: Sequence contains no elements + + //测试前清空数据 + fsql.Delete().Where(a => a.Id > 0).ExecuteAffrows(); + sugar.Deleteable().Where(a => a.Id > 0).ExecuteCommand(); + + Console.WriteLine("插入性能:"); + Insert(1000, 1); + Console.Write(sb.ToString()); + sb.Clear(); + Insert(1000, 10); + Console.Write(sb.ToString()); + sb.Clear(); + + Insert(1, 1000); + Console.Write(sb.ToString()); + sb.Clear(); + Insert(1, 10000); + Console.Write(sb.ToString()); + sb.Clear(); + Insert(1, 50000); + Console.Write(sb.ToString()); + sb.Clear(); + + Console.WriteLine("查询性能:"); + Select(1000, 1); + Console.Write(sb.ToString()); + sb.Clear(); + Select(1000, 10); + Console.Write(sb.ToString()); + sb.Clear(); + + Select(1, 1000); + Console.Write(sb.ToString()); + sb.Clear(); + Select(1, 10000); + Console.Write(sb.ToString()); + sb.Clear(); + Select(1, 50000); + Console.Write(sb.ToString()); + sb.Clear(); + Select(1, 100000); + Console.Write(sb.ToString()); + sb.Clear(); + + Console.Write(sb.ToString()); + Console.WriteLine("测试结束,按任意键退出..."); + Console.ReadKey(); + } + + static void Select(int forTime, int size) { + Stopwatch sw = new Stopwatch(); + + sw.Restart(); + for (var a = 0; a < forTime; a++) + fsql.Select().Limit(size).ToList(); + sw.Stop(); + sb.AppendLine($"FreeSql Select {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms"); + + sw.Restart(); + for (var a = 0; a < forTime; a++) + sugar.Queryable().Take(size).ToList(); + sw.Stop(); + sb.AppendLine($"SqlSugar Select {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms\r\n"); + } + + static void Insert(int forTime, int size) { + var songs = Enumerable.Range(0, size).Select(a => new Song { + Create_time = DateTime.Now, + Is_deleted = false, + Title = $"Insert_{a}", + Url = $"Url_{a}" + }).ToArray(); + + //预热 + fsql.Insert(songs.First()).ExecuteAffrows(); + sugar.Insertable(songs.First()).ExecuteCommand(); + Stopwatch sw = new Stopwatch(); + + sw.Restart(); + for (var a = 0; a < forTime; a++) + fsql.Insert(songs).ExecuteAffrows(); + sw.Stop(); + sb.AppendLine($"FreeSql Insert {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms"); + + sw.Restart(); + for (var a = 0; a < forTime; a++) + sugar.Insertable(songs).ExecuteCommand(); + sw.Stop(); + + sb.AppendLine($"SqlSugar Insert {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms\r\n"); + } + } + + [Table(Name = "freesql_song")] + [SugarTable("sugar_song")] + public class Song { + [Column(IsIdentity = true)] + [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] + public int Id { get; set; } + public DateTime? Create_time { get; set; } + public bool? Is_deleted { get; set; } + public string Title { get; set; } + public string Url { get; set; } + + [SugarColumn(IsIgnore = true)] + public virtual ICollection Tags { get; set; } + } + [Table(Name = "freesql_song_tag")] + [SugarTable("sugar_song_tag")] + public class Song_tag { + public int Song_id { get; set; } + [SugarColumn(IsIgnore = true)] + public virtual Song Song { get; set; } + + public int Tag_id { get; set; } + [SugarColumn(IsIgnore = true)] + public virtual Tag Tag { get; set; } + } + [Table(Name = "freesql_tag")] + [SugarTable("sugar_tag")] + public class Tag { + [Column(IsIdentity = true)] + [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] + public int Id { get; set; } + public int? Parent_id { get; set; } + [SugarColumn(IsIgnore = true)] + public virtual Tag Parent { get; set; } + + public decimal? Ddd { get; set; } + public string Name { get; set; } + + [SugarColumn(IsIgnore = true)] + public virtual ICollection Songs { get; set; } + [SugarColumn(IsIgnore = true)] + public virtual ICollection Tags { get; set; } + } +} diff --git a/Examples/orm_vs/orm_vs.csproj b/Examples/orm_vs/orm_vs.csproj new file mode 100644 index 00000000..95067184 --- /dev/null +++ b/Examples/orm_vs/orm_vs.csproj @@ -0,0 +1,16 @@ + + + + Exe + netcoreapp2.2 + + + + + + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index ee1e8424..5a087470 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.3.17 + 0.3.18 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.sln b/FreeSql.sln index d0391d46..f1b215f1 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -30,6 +30,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "domain_01", "Examples\domai EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "net461_console_01", "Examples\net461_console_01\net461_console_01.csproj", "{0637A778-338E-4096-B439-32B18306C75F}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "orm_vs", "Examples\orm_vs\orm_vs.csproj", "{1A5EC2EB-8C2B-4547-8AC6-EB5C0DE0CA81}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -160,6 +162,18 @@ Global {0637A778-338E-4096-B439-32B18306C75F}.Release|x64.Build.0 = Release|Any CPU {0637A778-338E-4096-B439-32B18306C75F}.Release|x86.ActiveCfg = Release|Any CPU {0637A778-338E-4096-B439-32B18306C75F}.Release|x86.Build.0 = Release|Any CPU + {1A5EC2EB-8C2B-4547-8AC6-EB5C0DE0CA81}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1A5EC2EB-8C2B-4547-8AC6-EB5C0DE0CA81}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1A5EC2EB-8C2B-4547-8AC6-EB5C0DE0CA81}.Debug|x64.ActiveCfg = Debug|Any CPU + {1A5EC2EB-8C2B-4547-8AC6-EB5C0DE0CA81}.Debug|x64.Build.0 = Debug|Any CPU + {1A5EC2EB-8C2B-4547-8AC6-EB5C0DE0CA81}.Debug|x86.ActiveCfg = Debug|Any CPU + {1A5EC2EB-8C2B-4547-8AC6-EB5C0DE0CA81}.Debug|x86.Build.0 = Debug|Any CPU + {1A5EC2EB-8C2B-4547-8AC6-EB5C0DE0CA81}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1A5EC2EB-8C2B-4547-8AC6-EB5C0DE0CA81}.Release|Any CPU.Build.0 = Release|Any CPU + {1A5EC2EB-8C2B-4547-8AC6-EB5C0DE0CA81}.Release|x64.ActiveCfg = Release|Any CPU + {1A5EC2EB-8C2B-4547-8AC6-EB5C0DE0CA81}.Release|x64.Build.0 = Release|Any CPU + {1A5EC2EB-8C2B-4547-8AC6-EB5C0DE0CA81}.Release|x86.ActiveCfg = Release|Any CPU + {1A5EC2EB-8C2B-4547-8AC6-EB5C0DE0CA81}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -170,6 +184,7 @@ Global {C9940A46-D265-4088-9561-5A42ACEDA7AE} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} {A23D0455-CA7B-442D-827E-C4C7E84F9084} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} {0637A778-338E-4096-B439-32B18306C75F} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} + {1A5EC2EB-8C2B-4547-8AC6-EB5C0DE0CA81} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98} diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 6c05348d..51414c63 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.3.17 + 0.3.18 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql/Interface/Curd/IInsert.cs b/FreeSql/Interface/Curd/IInsert.cs index 328acdd2..2dd8ca90 100644 --- a/FreeSql/Interface/Curd/IInsert.cs +++ b/FreeSql/Interface/Curd/IInsert.cs @@ -21,6 +21,12 @@ namespace FreeSql { /// IInsert AppendData(T1 source); /// + /// 追加准备插入的实体 + /// + /// 实体 + /// + IInsert AppendData(T1[] source); + /// /// 追加准备插入的实体集合 /// /// 实体集合 diff --git a/FreeSql/Interface/IFreeSql.cs b/FreeSql/Interface/IFreeSql.cs index c56f9421..cb24c141 100644 --- a/FreeSql/Interface/IFreeSql.cs +++ b/FreeSql/Interface/IFreeSql.cs @@ -19,6 +19,13 @@ public interface IFreeSql { /// IInsert Insert(T1 source) where T1 : class; /// + /// 插入数据,传入实体数组 + /// + /// + /// + /// + IInsert Insert(T1[] source) where T1 : class; + /// /// 插入数据,传入实体集合 /// /// diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index e902fcbc..c33a0d9e 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -45,6 +45,10 @@ namespace FreeSql.Internal.CommonProvider { if (source != null) _source.Add(source); return this; } + public IInsert AppendData(T1[] source) { + if (source != null) _source.AddRange(source); + return this; + } public IInsert AppendData(IEnumerable source) { if (source != null) _source.AddRange(source.Where(a => a != null)); return this; diff --git a/FreeSql/MySql/MySqlProvider.cs b/FreeSql/MySql/MySqlProvider.cs index ad45157a..ac98e30d 100644 --- a/FreeSql/MySql/MySqlProvider.cs +++ b/FreeSql/MySql/MySqlProvider.cs @@ -25,6 +25,7 @@ namespace FreeSql.MySql { public ISelect Select(object dywhere) where T1 : class => new MySqlSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IInsert Insert() where T1 : class => new MySqlInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); public IUpdate Update() where T1 : class => new MySqlUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IUpdate Update(object dywhere) where T1 : class => new MySqlUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); diff --git a/FreeSql/Oracle/OracleProvider.cs b/FreeSql/Oracle/OracleProvider.cs index bfee74d7..da9317ee 100644 --- a/FreeSql/Oracle/OracleProvider.cs +++ b/FreeSql/Oracle/OracleProvider.cs @@ -16,6 +16,7 @@ namespace FreeSql.Oracle { public ISelect Select(object dywhere) where T1 : class => new OracleSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IInsert Insert() where T1 : class => new OracleInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); public IUpdate Update() where T1 : class => new OracleUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IUpdate Update(object dywhere) where T1 : class => new OracleUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); diff --git a/FreeSql/PostgreSQL/PostgreSQLProvider.cs b/FreeSql/PostgreSQL/PostgreSQLProvider.cs index 998bfa0a..6cd7e645 100644 --- a/FreeSql/PostgreSQL/PostgreSQLProvider.cs +++ b/FreeSql/PostgreSQL/PostgreSQLProvider.cs @@ -52,6 +52,7 @@ namespace FreeSql.PostgreSQL { public ISelect Select(object dywhere) where T1 : class => new PostgreSQLSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IInsert Insert() where T1 : class => new PostgreSQLInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); public IUpdate Update() where T1 : class => new PostgreSQLUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IUpdate Update(object dywhere) where T1 : class => new PostgreSQLUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); diff --git a/FreeSql/SqlServer/Curd/SqlServerSelect.cs b/FreeSql/SqlServer/Curd/SqlServerSelect.cs index 3b036309..b65b1efe 100644 --- a/FreeSql/SqlServer/Curd/SqlServerSelect.cs +++ b/FreeSql/SqlServer/Curd/SqlServerSelect.cs @@ -11,7 +11,7 @@ namespace FreeSql.SqlServer.Curd { class SqlServerSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { internal static string ToSqlStatic(CommonUtils _commonUtils, string _select, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, IFreeSql _orm) - => !(_commonUtils as SqlServerUtils).IsSelectRowNumber ? + => (_commonUtils as SqlServerUtils).IsSelectRowNumber ? ToSqlStaticRowNumber(_commonUtils, _select, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tableRuleInvoke, _orm) : ToSqlStaticOffsetFetchNext(_commonUtils, _select, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tableRuleInvoke, _orm); diff --git a/FreeSql/SqlServer/SqlServerProvider.cs b/FreeSql/SqlServer/SqlServerProvider.cs index f03172f4..2356e299 100644 --- a/FreeSql/SqlServer/SqlServerProvider.cs +++ b/FreeSql/SqlServer/SqlServerProvider.cs @@ -15,6 +15,7 @@ namespace FreeSql.SqlServer { public ISelect Select(object dywhere) where T1 : class => new SqlServerSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IInsert Insert() where T1 : class => new SqlServerInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); public IUpdate Update() where T1 : class => new SqlServerUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IUpdate Update(object dywhere) where T1 : class => new SqlServerUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); diff --git a/FreeSql/Sqlite/SqliteProvider.cs b/FreeSql/Sqlite/SqliteProvider.cs index 1b7e8c5c..7ebee7f6 100644 --- a/FreeSql/Sqlite/SqliteProvider.cs +++ b/FreeSql/Sqlite/SqliteProvider.cs @@ -16,6 +16,7 @@ namespace FreeSql.Sqlite { public ISelect Select(object dywhere) where T1 : class => new SqliteSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IInsert Insert() where T1 : class => new SqliteInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); public IUpdate Update() where T1 : class => new SqliteUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IUpdate Update(object dywhere) where T1 : class => new SqliteUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere);