Lith 10 ماه پیش
والد
کامیت
ef96c8abda

+ 33 - 11
test/Vitorm.Data.Benchmark/OrmRunner/BenchmarkRunner.cs

@@ -1,36 +1,58 @@
 using BenchmarkDotNet.Attributes;
+using BenchmarkDotNet.Configs;
 
 namespace App.OrmRunner
 {
-
+    [Config(typeof(Config))]
     //[Orderer(BenchmarkDotNet.Order.SummaryOrderPolicy.FastestToSlowest)]
     [InProcess]
     public class BenchmarkRunner
     {
-        [Params(100)]
-        public int N;
+        private class Config : ManualConfig
+        {
+            // https://benchmarkdotnet.org/articles/configs/configs.html
+            public Config()
+            {
+                WithOptions(ConfigOptions.DisableOptimizationsValidator);
+            }
+        }
+
+
+        //[Params(100)]
+        public int N = 100;
+
+        //[Params(true, false)]
+        public bool executeQuery = true;
+
+        [Params(false, true)]
+        public bool queryJoin = false;
+
+        //[Params(0, 10)]
+        public int? skip = 10;
+
+        [Params(10, 1000)]
+        public int take = 100;
+
+
+
+        [Params(typeof(Runner_Vitorm), typeof(Runner_EntityFramework), typeof(Runner_SqlSuger))]
+        public Type runner;
 
-        [Params(10, 100, 500, 1000)]
-        public int rowCount;
 
-        [Params(true, false)]
-        public bool queryJoin;
 
-        [Params(typeof(Runner_EntityFramework), typeof(Runner_Vitorm))]
-        public Type testType;
 
         IRunner queryTest;
 
         [GlobalSetup]
         public void Setup()
         {
-            queryTest = Activator.CreateInstance(testType) as IRunner;
+            queryTest = Activator.CreateInstance(runner) as IRunner;
         }
 
         [Benchmark]
         public void Run()
         {
-            var config = new RunConfig { repeatCount = N, queryJoin = queryJoin, take = rowCount };
+            var config = new RunConfig { repeatCount = N, executeQuery = executeQuery, queryJoin = queryJoin, skip = skip, take = take };
             queryTest.Run(config);
         }
     }

+ 0 - 15
test/Vitorm.Data.Benchmark/OrmRunner/IOrmRunner.cs

@@ -1,15 +0,0 @@
-namespace App.QueryTest
-{
-    public interface IBenchmarkQuery
-    {
-        void Query(QueryConfig config); 
-    }
-
-    public class QueryConfig 
-    {
-        public int repeatCount;
-
-        public int take;
-        public bool queryJoin;
-    }
-}

+ 7 - 3
test/Vitorm.Data.Benchmark/OrmRunner/IRunner.cs

@@ -2,14 +2,18 @@
 {
     public interface IRunner
     {
-        void Run(RunConfig config); 
+        void Run(RunConfig config);
     }
 
-    public class RunConfig 
+    public class RunConfig
     {
-        public int repeatCount;
+        public int repeatCount = 1;
 
+        public bool executeQuery;
+
+        public int? skip = 1;
         public int take;
         public bool queryJoin;
+
     }
 }

+ 0 - 95
test/Vitorm.Data.Benchmark/OrmRunner/QueryTest_EntityFramework.cs

@@ -1,95 +0,0 @@
-using Microsoft.EntityFrameworkCore;
-
-using Vit.Core.Util.ConfigurationManager;
-
-using Vitorm;
-
-namespace App.QueryTest
-{
-    public class QueryTest_EntityFramework : IBenchmarkQuery
-    {
-
-        MyDbContext myDbContext = new MyDbContext();
-        public IQueryable<User> GetQueryable() => myDbContext.users;
-
-
-        public void Query(QueryConfig config)
-        {
-            for (int i = 0; i < config.repeatCount; i++)
-            {
-                if (config.queryJoin) QueryJoin(config.take);
-                else Query(config.take);
-            }
-        }
-
-        public void QueryJoin(int take)
-        {
-            var queryable = GetQueryable();
-            var query =
-                    from user in queryable
-                    from father in queryable.Where(father => user.fatherId == father.id).DefaultIfEmpty()
-                    from mother in queryable.Where(mother => user.motherId == mother.id).DefaultIfEmpty()
-                    where user.id > 1
-                    orderby user.id
-                    select new
-                    {
-                        user,
-                        father,
-                        mother,
-                        testId = user.id + 100,
-                        hasFather = father.name != null ? true : false
-                    }
-                    ;
-
-            query = query.Skip(1).Take(take);
-
-            var userList = query.ToList();
-            var rowCount = query.Count();
-            if (rowCount != take) throw new Exception($"query failed, expected row count : {take} , actual count: {rowCount} ");
-        }
-
-        public void Query(int take)
-        {
-            var userSet = Data.Query<User>();
-            var query1 =
-                    from user in userSet
-                    where user.id > 1
-                    orderby user.id
-                    select user;
-
-            var query = query1.Skip(1).Take(take);
-
-            var userList = query.ToList();
-            var rowCount = query.Count();
-            if (rowCount != take) throw new Exception($"query failed, expected row count : {take} , actual count: {rowCount} ");
-        }
-
-
-
-
-        public class MyDbContext : Microsoft.EntityFrameworkCore.DbContext
-        {
-            public Microsoft.EntityFrameworkCore.DbSet<User> users { get; set; }
-            protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
-            {
-                var connectionString = Appsettings.json.GetStringByPath("Vitorm.Data[0].connectionString");
-                optionsBuilder.UseSqlite(connectionString);
-            }
-        }
-
-
-
-        // Entity Definition
-        [System.ComponentModel.DataAnnotations.Schema.Table("User")]
-        public class User
-        {
-            [System.ComponentModel.DataAnnotations.Key]
-            public int id { get; set; }
-            public string name { get; set; }
-            public DateTime? birth { get; set; }
-            public int? fatherId { get; set; }
-            public int? motherId { get; set; }
-        }
-
-    }
-}

+ 0 - 100
test/Vitorm.Data.Benchmark/OrmRunner/QueryTest_Vitorm.cs

@@ -1,100 +0,0 @@
-using Vitorm;
-
-namespace App.QueryTest
-{
-    public class QueryTest_Vitorm : IBenchmarkQuery
-    {
-        public static void InitDb()
-        {
-            Data.Drop<User>();
-            Data.Create<User>();
-
-            var users = new List<User> {
-                    new User { id=1, name="u146", fatherId=4, motherId=6 },
-                    new User { id=2, name="u246", fatherId=4, motherId=6 },
-                    new User { id=3, name="u356", fatherId=5, motherId=6 },
-                    new User { id=4, name="u400" },
-                    new User { id=5, name="u500" },
-                    new User { id=6, name="u600" },
-                };
-            Data.AddRange(users);
-
-            users = Enumerable.Range(7, 1000).Select(id => new User { id = id, name = "user" + id }).ToList();
-            Data.AddRange(users);
-        }
-
-
-        IQueryable<User> users = Data.Query<User>();
-        public IQueryable<User> GetQueryable() => users;
-
-
-
-
-        public void Query(QueryConfig config)
-        {
-            for (int i = 0; i < config.repeatCount; i++)
-            {
-                if (config.queryJoin) QueryJoin(config.take);
-                else Query(config.take);
-            }
-        }
-
-        public void QueryJoin(int take)
-        {
-            var queryable = GetQueryable();
-            var query =
-                    from user in queryable
-                    from father in queryable.Where(father => user.fatherId == father.id).DefaultIfEmpty()
-                    from mother in queryable.Where(mother => user.motherId == mother.id).DefaultIfEmpty()
-                    where user.id > 1
-                    orderby user.id
-                    select new
-                    {
-                        user,
-                        father,
-                        mother,
-                        testId = user.id + 100,
-                        hasFather = father.name != null ? true : false
-                    }
-                    ;
-
-            query = query.Skip(1).Take(take);
-
-            var userList = query.ToList();
-            var rowCount = userList.Count();
-            if (rowCount != take) throw new Exception($"query failed, expected row count : {take} , actual count: {rowCount} ");
-        }
-
-        public void Query(int take)
-        {
-            var userSet = Data.Query<User>();
-            var query1 =
-                    from user in userSet
-                    where user.id > 1
-                    orderby user.id
-                    select user;
-
-            var query = query1.Skip(1).Take(take);
-
-            var userList = query.ToList();
-            var rowCount = userList.Count();
-            if (rowCount != take) throw new Exception($"query failed, expected row count : {take} , actual count: {rowCount} ");
-        }
-
-
-
-
-        // Entity Definition
-        [System.ComponentModel.DataAnnotations.Schema.Table("User")]
-        public class User
-        {
-            [System.ComponentModel.DataAnnotations.Key]
-            public int id { get; set; }
-            public string name { get; set; }
-            public DateTime? birth { get; set; }
-            public int? fatherId { get; set; }
-            public int? motherId { get; set; }
-        }
-
-    }
-}

+ 62 - 26
test/Vitorm.Data.Benchmark/OrmRunner/Runner_EntityFramework.cs

@@ -1,76 +1,112 @@
 using Microsoft.EntityFrameworkCore;
+
 using Vit.Core.Util.ConfigurationManager;
 
 using Vitorm;
 
+
 namespace App.OrmRunner
 {
     public partial class Runner_EntityFramework : IRunner
     {
+        RunConfig config;
+
+        int? skip => config.skip;
+        int take => config.take;
+        bool executeQuery => config.executeQuery;
 
-        MyDbContext myDbContext = new MyDbContext();
-        public IQueryable<User> GetQueryable() => myDbContext.users;
+
+
+        IQueryable<User> userQuery;
+        public IQueryable<User> GetQueryable() => userQuery;
 
 
         public void Run(RunConfig config)
         {
+            this.config = config;
+
             for (int i = 0; i < config.repeatCount; i++)
             {
-                if (config.queryJoin) QueryJoin(config.take);
-                else Query(config.take);
+                using MyDbContext myDbContext = new MyDbContext();
+                userQuery = myDbContext.users;
+
+                if (config.queryJoin) QueryJoin();
+                else Query();
             }
         }
 
-        public void QueryJoin(int take)
+        #region Executor
+        int exceptUserId = 1;
+        public void QueryJoin()
         {
-            var queryable = GetQueryable();
+            var userSet = GetQueryable();
+
+            var minId = 1;
+            var config = new { maxId = 10000 };
+            var offsetId = 100;
+
             var query =
-                    from user in queryable
-                    from father in queryable.Where(father => user.fatherId == father.id).DefaultIfEmpty()
-                    from mother in queryable.Where(mother => user.motherId == mother.id).DefaultIfEmpty()
-                    where user.id > 1
+                    from user in userSet
+                    from father in userSet.Where(father => user.fatherId == father.id).DefaultIfEmpty()
+                    from mother in userSet.Where(mother => user.motherId == mother.id).DefaultIfEmpty()
+                    where user.id > minId && user.id < config.maxId && user.id != exceptUserId
                     orderby user.id
                     select new
                     {
                         user,
                         father,
                         mother,
-                        testId = user.id + 100,
+                        testId = user.id + offsetId,
                         hasFather = father.name != null ? true : false
                     }
                     ;
 
-            query = query.Skip(1).Take(take);
-
-            var userList = query.ToList();
-            var rowCount = userList.Count();
-            if (rowCount != take) throw new Exception($"query failed, expected row count : {take} , actual count: {rowCount} ");
+            Execute(query);
         }
 
-        public void Query(int take)
+        public void Query()
         {
-            var userSet = Data.Query<User>();
-            var query1 =
+            var userSet = GetQueryable();
+
+            var minId = 1;
+            var config = new { maxId = 10000 };
+
+            var query =
                     from user in userSet
-                    where user.id > 1
+                    where user.id > minId && user.id < config.maxId && user.id != exceptUserId
                     orderby user.id
                     select user;
 
-            var query = query1.Skip(1).Take(take);
-
-            var userList = query.ToList();
-            var rowCount = userList.Count();
-            if (rowCount != take) throw new Exception($"query failed, expected row count : {take} , actual count: {rowCount} ");
+            Execute(query);
         }
+        #endregion
 
+        public void Execute<Result>(IQueryable<Result> query)
+        {
+            if (skip > 0) query = query.Skip(skip.Value);
+            query = query.Take(take);
+
+            if (executeQuery)
+            {
+                var userList = query.ToList();
+                var rowCount = userList.Count();
+                if (rowCount != take) throw new Exception($"query failed, expected row count : {take} , actual count: {rowCount} ");
+            }
+            else
+            {
+                var sql = query.ToQueryString();
+                if (string.IsNullOrEmpty(sql)) throw new Exception($"query failed, can not generated sql script");
+            }
+        }
 
 
         public class MyDbContext : Microsoft.EntityFrameworkCore.DbContext
         {
             public Microsoft.EntityFrameworkCore.DbSet<User> users { get; set; }
+
+            static string connectionString = Appsettings.json.GetStringByPath("Vitorm.Data[0].connectionString");
             protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
             {
-                var connectionString = Appsettings.json.GetStringByPath("Vitorm.Data[0].connectionString");
                 optionsBuilder.UseSqlite(connectionString);
             }
         }

+ 168 - 0
test/Vitorm.Data.Benchmark/OrmRunner/Runner_SqlSugar.cs

@@ -0,0 +1,168 @@
+using SqlSugar;
+
+using Vit.Core.Util.ConfigurationManager;
+
+
+namespace App.OrmRunner
+{
+    public class Runner_SqlSuger : IRunner
+    {
+        RunConfig config;
+
+        int? skip => config.skip;
+        int? take => config.take;
+        bool executeQuery => config.executeQuery;
+
+
+        static string connectionString = Appsettings.json.GetStringByPath("Vitorm.Data[0].connectionString");
+
+
+        SqlSugarClient db;
+        public string sql;
+        public void Run(RunConfig config)
+        {
+            this.config = config;
+
+
+            for (int i = 0; i < config.repeatCount; i++)
+            {
+
+                Action<SqlSugarClient> configAction;
+                if (executeQuery)
+                {
+                    configAction = db => { };
+                }
+                else
+                {
+                    configAction = db =>
+                    {
+                        db.Aop.OnLogExecuting = (sql, pars) =>
+                        {
+                            //Console.WriteLine(sql); //输出sql,查看执行sql 性能无影响
+
+                            //获取原生SQL推荐 5.1.4.63  性能OK
+                            var nativeSql = UtilMethods.GetNativeSql(sql, pars);
+                            //Console.WriteLine(nativeSql);
+                            sql = nativeSql;
+
+                            //获取无参数化SQL 对性能有影响,特别大的SQL参数多的,调试使用
+                            //var sqlString = UtilMethods.GetSqlString(DbType.SqlServer, sql, pars);
+                            //Console.WriteLine(sqlString);
+                        };
+                    };
+                }
+                using SqlSugarClient db = new SqlSugarClient(new ConnectionConfig
+                {
+                    DbType = DbType.Sqlite,
+                    ConnectionString = connectionString,
+                    IsAutoCloseConnection = true,
+                }, configAction);
+                this.db = db;
+
+                if (config.queryJoin) QueryJoin();
+                else Query();
+            }
+        }
+
+        #region Executor
+        int exceptUserId = 1;
+        public void QueryJoin()
+        {
+            var minId = 1;
+            var config = new { maxId = 10000 };
+            var offsetId = 100;
+
+            //var query =
+            //        from user in userSet
+            //        from father in userSet.Where(father => user.fatherId == father.id).DefaultIfEmpty()
+            //        from mother in userSet.Where(mother => user.motherId == mother.id).DefaultIfEmpty()
+            //        where user.id > minId && user.id < config.maxId && user.id != exceptUserId
+            //        orderby user.id
+            //        select new
+            //        {
+            //            user,
+            //            father,
+            //            mother,
+            //            testId = user.id + offsetId,
+            //            hasFather = father.name != null ? true : false
+            //        }
+            //        ;
+
+            var query = db.Queryable<User>().LeftJoin<User>((user, father) => user.fatherId == father.id)
+                .LeftJoin<User>((user, father, mother) => user.fatherId == mother.id)
+                .Where((user, father, mother) => user.id > minId && user.id < config.maxId && user.id != exceptUserId)
+                .OrderBy((user, father, mother) => user.id, OrderByType.Asc)
+                .Select((user, father, mother) =>
+                new
+                {
+                    user,
+                    father,
+                    mother,
+                    testId = user.id + offsetId,
+                    hasFather = father.name != null ? true : false
+                });
+            
+
+            Execute(query);
+        }
+
+        public void Query()
+        {
+
+            var minId = 1;
+            var config = new { maxId = 10000 };
+
+            //var query =
+            //        from user in userSet
+            //        where user.id > minId && user.id < config.maxId && user.id != exceptUserId
+            //        orderby user.id
+            //        select user;
+
+            var query = db.Queryable<User>().Where(user => user.id > minId && user.id < config.maxId && user.id != exceptUserId).OrderBy(user => user.id, OrderByType.Asc);
+
+            Execute(query);
+        }
+        #endregion
+
+        public void Execute<Result>(ISugarQueryable<Result> query)
+        {
+            if (skip.HasValue) query = query.Skip(skip.Value);
+            if (take.HasValue) query = query.Take(take.Value);
+
+            if (executeQuery)
+            {
+                var userList = query.ToList();
+                var rowCount = userList.Count();
+                if (rowCount != take) throw new Exception($"query failed, expected row count : {take} , actual count: {rowCount} ");
+            }
+            else
+            {
+                sql = null;
+                var count = query.Count();
+                //query.Single();
+
+                //if (string.IsNullOrEmpty(sql))
+                //    throw new Exception($"query failed, can not generated sql script");
+            }
+        }
+
+
+ 
+
+
+
+        // Entity Definition
+        [SugarTable("User")]
+        public class User
+        {
+            [SugarColumn(IsPrimaryKey = true, IsIdentity = false)]
+            public int id { get; set; }
+            public string name { get; set; }
+            public DateTime? birth { get; set; }
+            public int? fatherId { get; set; }
+            public int? motherId { get; set; }
+        }
+
+
+    }
+}

+ 54 - 25
test/Vitorm.Data.Benchmark/OrmRunner/Runner_Vitorm.cs

@@ -5,62 +5,91 @@ namespace App.OrmRunner
     public partial class Runner_Vitorm : IRunner
     {
 
-        IQueryable<User> users = Data.Query<User>();
-        public IQueryable<User> GetQueryable() => users;
+        RunConfig config;
 
+        int? skip => config.skip;
+        int take => config.take;
+        bool executeQuery => config.executeQuery;
+
+
+        IQueryable<User> userQuery;
+        public IQueryable<User> GetQueryable() => userQuery;
 
         public void Run(RunConfig config)
         {
+            this.config = config;
+
             for (int i = 0; i < config.repeatCount; i++)
             {
-                if (config.queryJoin) QueryJoin(config.take);
-                else Query(config.take);
+                userQuery = Data.Query<User>();
+                if (config.queryJoin) QueryJoin();
+                else Query();
             }
         }
 
-        public void QueryJoin(int take)
+        #region Executor
+        int exceptUserId = 1;
+        public void QueryJoin()
         {
-            var queryable = GetQueryable();
+            var userSet = GetQueryable();
+
+            var minId = 1;
+            var config = new { maxId = 10000 };
+            var offsetId = 100;
+
             var query =
-                    from user in queryable
-                    from father in queryable.Where(father => user.fatherId == father.id).DefaultIfEmpty()
-                    from mother in queryable.Where(mother => user.motherId == mother.id).DefaultIfEmpty()
-                    where user.id > 1
+                    from user in userSet
+                    from father in userSet.Where(father => user.fatherId == father.id).DefaultIfEmpty()
+                    from mother in userSet.Where(mother => user.motherId == mother.id).DefaultIfEmpty()
+                    where user.id > minId && user.id < config.maxId && user.id != exceptUserId
                     orderby user.id
                     select new
                     {
                         user,
                         father,
                         mother,
-                        testId = user.id + 100,
+                        testId = user.id + offsetId,
                         hasFather = father.name != null ? true : false
                     }
                     ;
 
-            query = query.Skip(1).Take(take);
-
-            var userList = query.ToList();
-            var rowCount = userList.Count();
-            if (rowCount != take) throw new Exception($"query failed, expected row count : {take} , actual count: {rowCount} ");
+            Execute(query);
         }
 
-        public void Query(int take)
+        public void Query()
         {
-            var userSet = Data.Query<User>();
-            var query1 =
+            var userSet = GetQueryable();
+
+            var minId = 1;
+            var config = new { maxId = 10000 };
+
+            var query =
                     from user in userSet
-                    where user.id > 1
+                    where user.id > minId && user.id < config.maxId && user.id != exceptUserId
                     orderby user.id
                     select user;
 
-            var query = query1.Skip(1).Take(take);
-
-            var userList = query.ToList();
-            var rowCount = userList.Count();
-            if (rowCount != take) throw new Exception($"query failed, expected row count : {take} , actual count: {rowCount} ");
+            Execute(query);
         }
+        #endregion
 
+        public void Execute<Result>(IQueryable<Result> query)
+        {
+            if (skip > 0) query = query.Skip(skip.Value);
+            query = query.Take(take);
 
+            if (executeQuery)
+            {
+                var userList = query.ToList();
+                var rowCount = userList.Count();
+                if (rowCount != take) throw new Exception($"query failed, expected row count : {take} , actual count: {rowCount} ");
+            }
+            else
+            {
+                var sql = query.ToExecuteString();
+                if (string.IsNullOrEmpty(sql)) throw new Exception($"query failed, can not generated sql script");
+            }
+        }
 
 
         // Entity Definition

+ 7 - 7
test/Vitorm.Data.Benchmark/Program.cs

@@ -9,21 +9,21 @@ namespace App
         static void Main(string[] args)
         {
             // #1 init
-            //App.Runner.EnvSetup.InitDb();
+            App.Runner.EnvSetup.InitDb();
 
 
 
-            // #2
-            //new App.OrmRunner.Runner_Vitorm().Query(take: 100);
-            //new App.OrmRunner.Runner_Vitorm().QueryJoin(take: 100);
-            //new App.OrmRunner.Runner_EntityFramework().Query(take: 100);
-            //new App.OrmRunner.Runner_EntityFramework().QueryJoin(take: 100);
+            // #2 
+            //new App.OrmRunner.Runner_Vitorm().Run(new() { take = 100, queryJoin = true, executeQuery = true });
+            //new App.OrmRunner.Runner_EntityFramework().Run(new() { take = 100, queryJoin = true, executeQuery = true });
+            //new App.OrmRunner.Runner_SqlSuger().Run(new() { repeatCount = 100, take = 1000, queryJoin = true, executeQuery = true });
+            //new App.OrmRunner.Runner_SqlSuger().Run(new() { repeatCount = 100, take = 1000, queryJoin = false, executeQuery = true });
             var summary = BenchmarkRunner.Run<App.OrmRunner.BenchmarkRunner>();
 
 
 
             // #3
-            //new App.Runner.ReduceMember.BenchmarkRunner().QueryJoin();
+            //new App.Runner.BenchmarkRunner_ReduceMember().Run();
             //BenchmarkRunner.Run<App.Runner.BenchmarkRunner_ReduceMember>();
 
         }

+ 41 - 28
test/Vitorm.Data.Benchmark/Runner/BenchmarkRunner_ReduceMember.cs

@@ -11,16 +11,26 @@ namespace App.Runner
     public partial class BenchmarkRunner_ReduceMember
     {
         [Params(100)]
-        public int N;
+        public int N = 1;
 
         [Params(true, false)]
+        public bool executeQuery = false;
+
+        [Params(false, true)]
         public bool queryJoin = true;
 
-        //[Params(true, false)]
+        [Params(true, false)]
         public bool reduceMember = true;
 
-        [Params(true, false)]
-        public bool executeQuery = false;
+        //[Params(0, 10)]
+        public int? skip = 10;
+        //[Params(10, 100, 1000)]
+        public int take = 100;
+
+
+
+        IQueryable<User> userQuery;
+        public IQueryable<User> GetQueryable() => userQuery;
 
 
         [GlobalSetup]
@@ -32,12 +42,8 @@ namespace App.Runner
         [Benchmark]
         public void Run()
         {
-            Run(N, queryJoin);
-        }
+            userQuery = Data.Query<User>();
 
-
-        public void Run(int N, bool queryJoin)
-        {
             for (int i = 0; i < N; i++)
             {
                 if (queryJoin) QueryJoin();
@@ -45,62 +51,69 @@ namespace App.Runner
             }
         }
 
+
+        #region Executor
+        int exceptUserId = 1;
         public void QueryJoin()
         {
-            var userSet = Data.Query<User>();
+            var userSet = GetQueryable();
 
             var minId = 1;
-            var config = new { maxId = 100, offsetId = 100 };
+            var config = new { maxId = 10000 };
+            var offsetId = 100;
 
             var query =
                     from user in userSet
                     from father in userSet.Where(father => user.fatherId == father.id).DefaultIfEmpty()
                     from mother in userSet.Where(mother => user.motherId == mother.id).DefaultIfEmpty()
-                    where user.id > minId && user.id < config.maxId
+                    where user.id > minId && user.id < config.maxId && user.id != exceptUserId
                     orderby user.id
                     select new
                     {
                         user,
                         father,
                         mother,
-                        testId = user.id + config.offsetId,
+                        testId = user.id + offsetId,
                         hasFather = father.name != null ? true : false
                     }
                     ;
 
-            query = query.Skip(1).Take(2);
-
-            if (executeQuery)
-            {
-                var userList = query.ToList();
-            }
-            else
-            {
-                var sql = query.ToExecuteString();
-            }
+            Execute(query);
         }
 
         public void Query()
         {
+            var userSet = GetQueryable();
+
             var minId = 1;
-            var config = new { maxId = 100 };
+            var config = new { maxId = 10000 };
 
-            var userSet = Data.Query<User>();
-            var query1 =
+            var query =
                     from user in userSet
-                    where user.id > minId && user.id < config.maxId
+                    where user.id > minId && user.id < config.maxId && user.id != exceptUserId
                     orderby user.id
                     select user;
 
-            var query = query1.Skip(1).Take(2);
+            Execute(query);
+        }
+        #endregion
+
+
+        public void Execute<Result>(IQueryable<Result> query)
+        {
+            if (skip > 0) query = query.Skip(skip.Value);
+            query = query.Take(take);
 
             if (executeQuery)
             {
                 var userList = query.ToList();
+                var rowCount = userList.Count();
+                if (rowCount != take) throw new Exception($"query failed, expected row count : {take} , actual count: {rowCount} ");
             }
             else
             {
                 var sql = query.ToExecuteString();
+                if (string.IsNullOrEmpty(sql)) throw new Exception($"query failed, can not generated sql script");
             }
         }
 

+ 1 - 1
test/Vitorm.Data.Benchmark/Runner/EnvSetup.cs

@@ -19,7 +19,7 @@ namespace App.Runner
                 };
             Data.AddRange(users);
 
-            users = Enumerable.Range(7, 1000).Select(id => new User { id = id, name = "user" + id }).ToList();
+            users = Enumerable.Range(7, 1500).Select(id => new User { id = id, name = "user" + id }).ToList();
             Data.AddRange(users);
         }
 

+ 1 - 0
test/Vitorm.Data.Benchmark/Vitorm.Data.Benchmark.csproj

@@ -12,6 +12,7 @@
       <PackageReference Include="BenchmarkDotNet" Version="0.13.12" />
       <PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.31" />
       <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.31" />
+      <PackageReference Include="SqlSugarCore" Version="5.1.4.160" />
     </ItemGroup>
 
     <ItemGroup>