diff --git a/Examples/orm_vs/Program.cs b/Examples/orm_vs/Program.cs index 0a1b1ef5..929ebbf7 100644 --- a/Examples/orm_vs/Program.cs +++ b/Examples/orm_vs/Program.cs @@ -365,9 +365,9 @@ namespace orm_vs var testlist1 = fsql.Select().OrderBy(a => a.id).ToList(); var testlist2 = new List(); - fsql.Select().OrderBy(a => a.id).ToChunk(0, list => + fsql.Select().OrderBy(a => a.id).ToChunk(2, fetch => { - testlist2.AddRange(list); + testlist2.AddRange(fetch.Object); }); //sugar.Aop.OnLogExecuted = (s, e) => diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 132d875e..4854f49c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,6 +125,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -479,5 +486,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs index 3a792b77..85056d7b 100644 --- a/FreeSql.Tests/FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs @@ -170,14 +170,14 @@ namespace FreeSql.Tests.PerformanceTest time.Restart(); var adolist1 = new List(); - g.mysql.Ado.ExecuteReader(dr => + g.mysql.Ado.ExecuteReader(fetch => { var xim = new xxx(); - dr.GetValue(0); - dr.GetValue(1); - dr.GetValue(2); - dr.GetValue(3); - dr.GetValue(4); + fetch.Object.GetValue(0); + fetch.Object.GetValue(1); + fetch.Object.GetValue(2); + fetch.Object.GetValue(3); + fetch.Object.GetValue(4); adolist1.Add(xim); }, "select * from freesql_song"); time.Stop(); @@ -185,14 +185,14 @@ namespace FreeSql.Tests.PerformanceTest time.Restart(); adolist1 = new List(); - g.mysql.Ado.ExecuteReader(dr => + g.mysql.Ado.ExecuteReader(fetch => { var xim = new xxx(); - dr.GetFieldValue(0); - dr.GetFieldValue(1); - dr.GetFieldValue(2); - dr.GetFieldValue(3); - dr.GetFieldValue(4); + fetch.Object.GetFieldValue(0); + fetch.Object.GetFieldValue(1); + fetch.Object.GetFieldValue(2); + fetch.Object.GetFieldValue(3); + fetch.Object.GetFieldValue(4); adolist1.Add(xim); }, "select * from freesql_song"); time.Stop(); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/OnDuplicateKeyUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/OnDuplicateKeyUpdateTest.cs index 81ad6cab..e3fa639d 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/OnDuplicateKeyUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/OnDuplicateKeyUpdateTest.cs @@ -21,10 +21,10 @@ namespace FreeSql.Tests.MySqlConnector { g.mysql.Delete(new[] { 100, 101, 102 }).ExecuteAffrows(); var odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 100, title = "title-100", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnDuplicateKeyUpdate(); - Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(100, 'title-100', '2000-01-01 00:00:00.000') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(100, 'title-100', '2000-01-01 00:00:00.000') ON DUPLICATE KEY UPDATE `title` = VALUES(`title`), -`time` = VALUES(`time`)"); +`time` = VALUES(`time`)", odku1.ToSql()); Assert.Equal(1, odku1.ExecuteAffrows()); var odku2 = g.mysql.Insert(new[] { @@ -32,10 +32,10 @@ ON DUPLICATE KEY UPDATE new TestOnDuplicateKeyUpdateInfo { id = 101, title = "title-101", time = DateTime.Parse("2000-01-01") }, new TestOnDuplicateKeyUpdateInfo { id = 102, title = "title-102", time = DateTime.Parse("2000-01-01") } }).NoneParameter().OnDuplicateKeyUpdate(); - Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(100, 'title-100', '2000-01-01 00:00:00.000'), (101, 'title-101', '2000-01-01 00:00:00.000'), (102, 'title-102', '2000-01-01 00:00:00.000') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(100, 'title-100', '2000-01-01 00:00:00.000'), (101, 'title-101', '2000-01-01 00:00:00.000'), (102, 'title-102', '2000-01-01 00:00:00.000') ON DUPLICATE KEY UPDATE `title` = VALUES(`title`), -`time` = VALUES(`time`)"); +`time` = VALUES(`time`)", odku2.ToSql()); odku2.ExecuteAffrows(); } @@ -44,10 +44,10 @@ ON DUPLICATE KEY UPDATE { g.mysql.Delete(new[] { 200, 201, 202 }).ExecuteAffrows(); var odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }).IgnoreColumns(a => a.time).NoneParameter().OnDuplicateKeyUpdate(); - Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200') ON DUPLICATE KEY UPDATE `title` = VALUES(`title`), -`time` = '2000-01-01 00:00:00.000'"); +`time` = '2000-01-01 00:00:00.000'", odku1.ToSql()); Assert.Equal(1, odku1.ExecuteAffrows()); var odku2 = g.mysql.Insert(new[] { @@ -55,21 +55,21 @@ ON DUPLICATE KEY UPDATE new TestOnDuplicateKeyUpdateInfo { id = 201, title = "title-201", time = DateTime.Parse("2000-01-01") }, new TestOnDuplicateKeyUpdateInfo { id = 202, title = "title-202", time = DateTime.Parse("2000-01-01") } }).IgnoreColumns(a => a.time).NoneParameter().OnDuplicateKeyUpdate(); - Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') ON DUPLICATE KEY UPDATE `title` = VALUES(`title`), `time` = CASE `id` WHEN 200 THEN '2000-01-01 00:00:00.000' WHEN 201 THEN '2000-01-01 00:00:00.000' -WHEN 202 THEN '2000-01-01 00:00:00.000' END"); +WHEN 202 THEN '2000-01-01 00:00:00.000' END", odku2.ToSql()); odku2.ExecuteAffrows(); g.mysql.Delete(new[] { 200, 201, 202 }).ExecuteAffrows(); odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }).IgnoreColumns(a => a.time).NoneParameter().OnDuplicateKeyUpdate().IgnoreColumns(a => a.title); - Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200') ON DUPLICATE KEY UPDATE -`time` = '2000-01-01 00:00:00.000'"); +`time` = '2000-01-01 00:00:00.000'", odku1.ToSql()); Assert.Equal(1, odku1.ExecuteAffrows()); odku2 = g.mysql.Insert(new[] { @@ -77,12 +77,12 @@ ON DUPLICATE KEY UPDATE new TestOnDuplicateKeyUpdateInfo { id = 201, title = "title-201", time = DateTime.Parse("2000-01-01") }, new TestOnDuplicateKeyUpdateInfo { id = 202, title = "title-202", time = DateTime.Parse("2000-01-01") } }).IgnoreColumns(a => a.time).NoneParameter().OnDuplicateKeyUpdate().IgnoreColumns(a => a.title); - Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') ON DUPLICATE KEY UPDATE `time` = CASE `id` WHEN 200 THEN '2000-01-01 00:00:00.000' WHEN 201 THEN '2000-01-01 00:00:00.000' -WHEN 202 THEN '2000-01-01 00:00:00.000' END"); +WHEN 202 THEN '2000-01-01 00:00:00.000' END", odku2.ToSql()); odku2.ExecuteAffrows(); } @@ -91,10 +91,10 @@ WHEN 202 THEN '2000-01-01 00:00:00.000' END"); { g.mysql.Delete(new[] { 300, 301, 302 }).ExecuteAffrows(); var odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }).InsertColumns(a => a.title).NoneParameter().OnDuplicateKeyUpdate(); - Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300') ON DUPLICATE KEY UPDATE `title` = VALUES(`title`), -`time` = '2000-01-01 00:00:00.000'"); +`time` = '2000-01-01 00:00:00.000'", odku1.ToSql()); Assert.Equal(1, odku1.ExecuteAffrows()); var odku2 = g.mysql.Insert(new[] { @@ -102,21 +102,21 @@ ON DUPLICATE KEY UPDATE new TestOnDuplicateKeyUpdateInfo { id = 301, title = "title-301", time = DateTime.Parse("2000-01-01") }, new TestOnDuplicateKeyUpdateInfo { id = 302, title = "title-302", time = DateTime.Parse("2000-01-01") } }).InsertColumns(a => a.title).NoneParameter().OnDuplicateKeyUpdate(); - Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') ON DUPLICATE KEY UPDATE `title` = VALUES(`title`), `time` = CASE `id` WHEN 300 THEN '2000-01-01 00:00:00.000' WHEN 301 THEN '2000-01-01 00:00:00.000' -WHEN 302 THEN '2000-01-01 00:00:00.000' END"); +WHEN 302 THEN '2000-01-01 00:00:00.000' END", odku2.ToSql()); odku2.ExecuteAffrows(); g.mysql.Delete(new[] { 300, 301, 302 }).ExecuteAffrows(); odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }).InsertColumns(a => a.title).NoneParameter().OnDuplicateKeyUpdate().UpdateColumns(a => a.time); - Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300') ON DUPLICATE KEY UPDATE -`time` = '2000-01-01 00:00:00.000'"); +`time` = '2000-01-01 00:00:00.000'", odku1.ToSql()); Assert.Equal(1, odku1.ExecuteAffrows()); odku2 = g.mysql.Insert(new[] { @@ -124,12 +124,12 @@ ON DUPLICATE KEY UPDATE new TestOnDuplicateKeyUpdateInfo { id = 301, title = "title-301", time = DateTime.Parse("2000-01-01") }, new TestOnDuplicateKeyUpdateInfo { id = 302, title = "title-302", time = DateTime.Parse("2000-01-01") } }).InsertColumns(a => a.title).NoneParameter().OnDuplicateKeyUpdate().UpdateColumns(a => a.time); - Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') ON DUPLICATE KEY UPDATE `time` = CASE `id` WHEN 300 THEN '2000-01-01 00:00:00.000' WHEN 301 THEN '2000-01-01 00:00:00.000' -WHEN 302 THEN '2000-01-01 00:00:00.000' END"); +WHEN 302 THEN '2000-01-01 00:00:00.000' END", odku2.ToSql()); odku2.ExecuteAffrows(); } @@ -138,9 +138,9 @@ WHEN 302 THEN '2000-01-01 00:00:00.000' END"); { g.mysql.Delete(new[] { 400, 401, 402 }).ExecuteAffrows(); var odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnDuplicateKeyUpdate().Set(a => a.time, DateTime.Parse("2020-1-1")); - Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') ON DUPLICATE KEY UPDATE -`time` = '2020-01-01 00:00:00.000'"); +`time` = '2020-01-01 00:00:00.000'", odku1.ToSql()); Assert.Equal(1, odku1.ExecuteAffrows()); var odku2 = g.mysql.Insert(new[] { @@ -148,18 +148,18 @@ ON DUPLICATE KEY UPDATE new TestOnDuplicateKeyUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") }, new TestOnDuplicateKeyUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") } }).NoneParameter().OnDuplicateKeyUpdate().Set(a => a.time, DateTime.Parse("2020-1-1")); - Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') ON DUPLICATE KEY UPDATE -`time` = '2020-01-01 00:00:00.000'"); +`time` = '2020-01-01 00:00:00.000'", odku2.ToSql()); odku2.ExecuteAffrows(); var dt2020 = DateTime.Parse("2020-1-1"); g.mysql.Delete(new[] { 400, 401, 402 }).ExecuteAffrows(); odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnDuplicateKeyUpdate().Set(a => a.time == dt2020); - Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') ON DUPLICATE KEY UPDATE -`time` = '2020-01-01 00:00:00.000'"); +`time` = '2020-01-01 00:00:00.000'", odku1.ToSql()); Assert.Equal(1, odku1.ExecuteAffrows()); odku2 = g.mysql.Insert(new[] { @@ -167,17 +167,17 @@ ON DUPLICATE KEY UPDATE new TestOnDuplicateKeyUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") }, new TestOnDuplicateKeyUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") } }).NoneParameter().OnDuplicateKeyUpdate().Set(a => a.time == dt2020); - Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') ON DUPLICATE KEY UPDATE -`time` = '2020-01-01 00:00:00.000'"); +`time` = '2020-01-01 00:00:00.000'", odku2.ToSql()); odku2.ExecuteAffrows(); g.mysql.Delete(new[] { 400, 401, 402 }).ExecuteAffrows(); odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnDuplicateKeyUpdate().Set(a => new { time = dt2020, title = a.title + "123" }); - Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') ON DUPLICATE KEY UPDATE -`time` = '2020-01-01 00:00:00.000', `title` = concat(`title`, '123')"); +`time` = '2020-01-01 00:00:00.000', `title` = concat(`title`, '123')", odku1.ToSql()); Assert.Equal(1, odku1.ExecuteAffrows()); odku2 = g.mysql.Insert(new[] { @@ -185,9 +185,9 @@ ON DUPLICATE KEY UPDATE new TestOnDuplicateKeyUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") }, new TestOnDuplicateKeyUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") } }).NoneParameter().OnDuplicateKeyUpdate().Set(a => new { time = dt2020, title = a.title + "123" }); - Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') ON DUPLICATE KEY UPDATE -`time` = '2020-01-01 00:00:00.000', `title` = concat(`title`, '123')"); +`time` = '2020-01-01 00:00:00.000', `title` = concat(`title`, '123')", odku2.ToSql()); odku2.ExecuteAffrows(); } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index dc3e9926..2fcf5adc 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1250,7 +1250,7 @@ false: 返回 2级 LeftJoin/InnerJoin/RightJoin 对象;true: 返回所有 LeftJoin/InnerJoin/RightJoin 的导航数据 - + 执行SQL查询,分块返回数据,可减少内存开销。比如读取10万条数据,每次返回100条处理。 @@ -2401,16 +2401,16 @@ 当前线程的事务 - + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 - + - + 查询,ExecuteReader(dr => {}, "select * from user where age > ?age", new { age = 25 }) @@ -2532,7 +2532,7 @@ - + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 @@ -2541,7 +2541,7 @@ - + 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) @@ -2933,104 +2933,89 @@ 转大写同步结构,适用 Oracle/达梦/人大金仓 - - - - + - 获取c#类型对象 - - - - - - - 获取ado.net读取方法, GetBoolean、GetInt64 - - - - - - - 序列化 - - - - - - - 反序列化 - - - - - - - 获取数据库枚举类型,适用 PostgreSQL - - - - - - - 如果实体类有自增属性,分成两个 List,有值的Item1 merge,无值的Item2 insert - - - - - - - AsType, Ctor, ClearData 三处地方需要重新加载 + 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 + 本功能会影响 IFreeSql 首次访问的速度。 + 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 - + - AsType, Ctor, ClearData 三处地方需要重新加载 + 不使用命令参数化执行,针对 Insert/Update - + - 动态读取 DescriptionAttribute 注释文本 + 是否生成命令参数化执行,针对 lambda 表达式解析 + 注意:常量不会参数化,变量才会做参数化 + var id = 100; + fsql.Select<T>().Where(a => a.id == id) 会参数化 + fsql.Select<T>().Where(a => a.id == 100) 不会参数化 - - - + - 通过属性的注释文本,通过 xml 读取 + 延时加载导航属性对象,导航属性需要声明 virtual - - Dict:key=属性名,value=注释 - + - 创建一个过滤器 + 将实体类型与数据库对比,返回DDL语句 - 名字 - 表达式 - + - 当前操作的数据 + 将实体类型集合与数据库对比,返回DDL语句 + 实体类型 + - + - 当前批次 + 将实体类型与数据库对比,返回DDL语句(指定表名) + 实体类型 + 指定表名对比 + - + - 总批次数量 + 同步实体类型到数据库 + 注意:生产环境中谨慎使用 + - + - me="entity"> + 同步实体类型集合到数据库 + 注意:生产环境中谨慎使用 + + + + + + 同步实体类型到数据库(指定表名) + 注意:生产环境中谨慎使用 + + 实体类型 + 指定表名对比 + + + + 根据 System.Type 获取数据库信息 + + + + + + + FreeSql FluentApi 配置实体,方法名与特性相同 + + + @@ -3298,6 +3283,11 @@ 此时 Value 的值格式为逗号分割:value1,value2,value3... 或者数组 + + + 是否放弃继续读取 + + 中间表,多对多 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index 101503ed..a7b61482 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -79,7 +79,7 @@ namespace FreeSql /// 数据块的大小 /// 处理数据块 /// false: 返回 2级 LeftJoin/InnerJoin/RightJoin 对象;true: 返回所有 LeftJoin/InnerJoin/RightJoin 的导航数据 - void ToChunk(int size, Action> done, bool includeNestedMembers = false); + void ToChunk(int size, Action>> done, bool includeNestedMembers = false); /// /// 执行SQL查询,返回 field 指定字段的记录,并以元组或基础类型(int,string,long)接收,记录不存在时返回 Count 为 0 的列表 /// diff --git a/FreeSql/Interface/IAdo.cs b/FreeSql/Interface/IAdo.cs index dade30c1..02626f8e 100644 --- a/FreeSql/Interface/IAdo.cs +++ b/FreeSql/Interface/IAdo.cs @@ -58,21 +58,21 @@ namespace FreeSql /// /// 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 /// - /// + /// /// /// /// - void ExecuteReader(Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - void ExecuteReader(DbTransaction transaction, Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - void ExecuteReader(DbConnection connection, DbTransaction transaction, Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + void ExecuteReader(Action> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + void ExecuteReader(DbTransaction transaction, Action> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + void ExecuteReader(DbConnection connection, DbTransaction transaction, Action> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// /// 查询,ExecuteReader(dr => {}, "select * from user where age > ?age", new { age = 25 }) /// /// /// - void ExecuteReader(Action readerHander, string cmdText, object parms = null); - void ExecuteReader(DbTransaction transaction, Action readerHander, string cmdText, object parms = null); - void ExecuteReader(DbConnection connection, DbTransaction transaction, Action readerHander, string cmdText, object parms = null); + void ExecuteReader(Action> fetchHandler, string cmdText, object parms = null); + void ExecuteReader(DbTransaction transaction, Action> fetchHandler, string cmdText, object parms = null); + void ExecuteReader(DbConnection connection, DbTransaction transaction, Action> fetchHandler, string cmdText, object parms = null); /// /// 查询 /// @@ -235,17 +235,17 @@ namespace FreeSql /// /// /// - Task ExecuteReaderAsync(Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task ExecuteReaderAsync(DbTransaction transaction, Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task ExecuteReaderAsync(Func, Task> readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task ExecuteReaderAsync(DbTransaction transaction, Func, Task> readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func, Task> readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// /// 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) /// /// /// - Task ExecuteReaderAsync(Func readerHander, string cmdText, object parms = null); - Task ExecuteReaderAsync(DbTransaction transaction, Func readerHander, string cmdText, object parms = null); - Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func readerHander, string cmdText, object parms = null); + Task ExecuteReaderAsync(Func, Task> readerHander, string cmdText, object parms = null); + Task ExecuteReaderAsync(DbTransaction transaction, Func, Task> readerHander, string cmdText, object parms = null); + Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func, Task> readerHander, string cmdText, object parms = null); /// /// 查询 /// diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs index 8d1d81d7..613f0e85 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs @@ -109,15 +109,15 @@ namespace FreeSql.Internal.CommonProvider string flag = null; int[] indexes = null; var props = GetQueryTypeProperties(type); - ExecuteReader(connection, transaction, dr => + ExecuteReader(connection, transaction, fetch => { if (indexes == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -125,7 +125,7 @@ namespace FreeSql.Internal.CommonProvider indexes = props.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag = sbflag.ToString(); } - ret.Add((T)Utils.ExecuteArrayRowReadClassOrTuple(flag, type, indexes, dr, 0, _util).Value); + ret.Add((T)Utils.ExecuteArrayRowReadClassOrTuple(flag, type, indexes, fetch.Object, 0, _util).Value); }, cmdType, cmdText, cmdParms); return ret; } @@ -149,7 +149,7 @@ namespace FreeSql.Internal.CommonProvider string flag2 = null; int[] indexes2 = null; var props2 = GetQueryTypeProperties(type2); - ExecuteReaderMultiple(2, connection, transaction, (dr, result) => + ExecuteReaderMultiple(2, connection, transaction, (fetch, result) => { switch (result) { @@ -158,9 +158,9 @@ namespace FreeSql.Internal.CommonProvider { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -168,16 +168,16 @@ namespace FreeSql.Internal.CommonProvider indexes1 = props1.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag1 = sbflag.ToString(); } - ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, dr, 0, _util).Value); + ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, fetch.Object, 0, _util).Value); break; case 1: if (indexes2 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -185,7 +185,7 @@ namespace FreeSql.Internal.CommonProvider indexes2 = props2.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag2 = sbflag.ToString(); } - ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, dr, 0, _util).Value); + ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, fetch.Object, 0, _util).Value); break; } }, cmdType, cmdText, cmdParms); @@ -217,7 +217,7 @@ namespace FreeSql.Internal.CommonProvider string flag3 = null; int[] indexes3 = null; var props3 = GetQueryTypeProperties(type3); - ExecuteReaderMultiple(3, connection, transaction, (dr, result) => + ExecuteReaderMultiple(3, connection, transaction, (fetch, result) => { switch (result) { @@ -226,9 +226,9 @@ namespace FreeSql.Internal.CommonProvider { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -236,16 +236,16 @@ namespace FreeSql.Internal.CommonProvider indexes1 = props1.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag1 = sbflag.ToString(); } - ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, dr, 0, _util).Value); + ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, fetch.Object, 0, _util).Value); break; case 1: if (indexes2 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -253,16 +253,16 @@ namespace FreeSql.Internal.CommonProvider indexes2 = props2.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag2 = sbflag.ToString(); } - ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, dr, 0, _util).Value); + ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, fetch.Object, 0, _util).Value); break; case 2: if (indexes3 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -270,7 +270,7 @@ namespace FreeSql.Internal.CommonProvider indexes3 = props3.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag3 = sbflag.ToString(); } - ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, dr, 0, _util).Value); + ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, fetch.Object, 0, _util).Value); break; } }, cmdType, cmdText, cmdParms); @@ -308,7 +308,7 @@ namespace FreeSql.Internal.CommonProvider string flag4 = null; int[] indexes4 = null; var props4 = GetQueryTypeProperties(type4); - ExecuteReaderMultiple(4, connection, transaction, (dr, result) => + ExecuteReaderMultiple(4, connection, transaction, (fetch, result) => { switch (result) { @@ -317,9 +317,9 @@ namespace FreeSql.Internal.CommonProvider { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -327,16 +327,16 @@ namespace FreeSql.Internal.CommonProvider indexes1 = props1.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag1 = sbflag.ToString(); } - ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, dr, 0, _util).Value); + ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, fetch.Object, 0, _util).Value); break; case 1: if (indexes2 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -344,16 +344,16 @@ namespace FreeSql.Internal.CommonProvider indexes2 = props2.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag2 = sbflag.ToString(); } - ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, dr, 0, _util).Value); + ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, fetch.Object, 0, _util).Value); break; case 2: if (indexes3 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -361,16 +361,16 @@ namespace FreeSql.Internal.CommonProvider indexes3 = props3.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag3 = sbflag.ToString(); } - ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, dr, 0, _util).Value); + ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, fetch.Object, 0, _util).Value); break; case 3: if (indexes4 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -378,7 +378,7 @@ namespace FreeSql.Internal.CommonProvider indexes4 = props4.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag4 = sbflag.ToString(); } - ret4.Add((T4)Utils.ExecuteArrayRowReadClassOrTuple(flag4, type4, indexes4, dr, 0, _util).Value); + ret4.Add((T4)Utils.ExecuteArrayRowReadClassOrTuple(flag4, type4, indexes4, fetch.Object, 0, _util).Value); break; } }, cmdType, cmdText, cmdParms); @@ -422,7 +422,7 @@ namespace FreeSql.Internal.CommonProvider string flag5 = null; int[] indexes5 = null; var props5 = GetQueryTypeProperties(type5); - ExecuteReaderMultiple(5, connection, transaction, (dr, result) => + ExecuteReaderMultiple(5, connection, transaction, (fetch, result) => { switch (result) { @@ -431,9 +431,9 @@ namespace FreeSql.Internal.CommonProvider { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -441,16 +441,16 @@ namespace FreeSql.Internal.CommonProvider indexes1 = props1.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag1 = sbflag.ToString(); } - ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, dr, 0, _util).Value); + ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, fetch.Object, 0, _util).Value); break; case 1: if (indexes2 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -458,16 +458,16 @@ namespace FreeSql.Internal.CommonProvider indexes2 = props2.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag2 = sbflag.ToString(); } - ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, dr, 0, _util).Value); + ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, fetch.Object, 0, _util).Value); break; case 2: if (indexes3 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -475,16 +475,16 @@ namespace FreeSql.Internal.CommonProvider indexes3 = props3.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag3 = sbflag.ToString(); } - ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, dr, 0, _util).Value); + ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, fetch.Object, 0, _util).Value); break; case 3: if (indexes4 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -492,16 +492,16 @@ namespace FreeSql.Internal.CommonProvider indexes4 = props4.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag4 = sbflag.ToString(); } - ret4.Add((T4)Utils.ExecuteArrayRowReadClassOrTuple(flag4, type4, indexes4, dr, 0, _util).Value); + ret4.Add((T4)Utils.ExecuteArrayRowReadClassOrTuple(flag4, type4, indexes4, fetch.Object, 0, _util).Value); break; case 4: if (indexes5 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -509,7 +509,7 @@ namespace FreeSql.Internal.CommonProvider indexes5 = props5.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag5 = sbflag.ToString(); } - ret5.Add((T5)Utils.ExecuteArrayRowReadClassOrTuple(flag5, type5, indexes5, dr, 0, _util).Value); + ret5.Add((T5)Utils.ExecuteArrayRowReadClassOrTuple(flag5, type5, indexes5, fetch.Object, 0, _util).Value); break; } }, cmdType, cmdText, cmdParms); @@ -517,13 +517,13 @@ namespace FreeSql.Internal.CommonProvider } #endregion - public void ExecuteReader(Action readerHander, string cmdText, object parms = null) => ExecuteReader(null, null, readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public void ExecuteReader(DbTransaction transaction, Action readerHander, string cmdText, object parms = null) => ExecuteReader(null, transaction, readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public void ExecuteReader(DbConnection connection, DbTransaction transaction, Action readerHander, string cmdText, object parms = null) => ExecuteReader(connection, transaction, readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public void ExecuteReader(Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReader(null, null, readerHander, cmdType, cmdText, cmdParms); - public void ExecuteReader(DbTransaction transaction, Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReader(null, transaction, readerHander, cmdType, cmdText, cmdParms); - public void ExecuteReader(DbConnection connection, DbTransaction transaction, Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderMultiple(1, connection, transaction, (dr, result) => readerHander(dr), cmdType, cmdText, cmdParms); - void ExecuteReaderMultiple(int multipleResult, DbConnection connection, DbTransaction transaction, Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public void ExecuteReader(Action> fetchHandler, string cmdText, object parms = null) => ExecuteReader(null, null, fetchHandler, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public void ExecuteReader(DbTransaction transaction, Action> fetchHandler, string cmdText, object parms = null) => ExecuteReader(null, transaction, fetchHandler, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public void ExecuteReader(DbConnection connection, DbTransaction transaction, Action> fetchHandler, string cmdText, object parms = null) => ExecuteReader(connection, transaction, fetchHandler, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public void ExecuteReader(Action> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReader(null, null, fetchHandler, cmdType, cmdText, cmdParms); + public void ExecuteReader(DbTransaction transaction, Action> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReader(null, transaction, fetchHandler, cmdType, cmdText, cmdParms); + public void ExecuteReader(DbConnection connection, DbTransaction transaction, Action> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderMultiple(1, connection, transaction, (fetch, result) => fetchHandler(fetch), cmdType, cmdText, cmdParms); + void ExecuteReaderMultiple(int multipleResult, DbConnection connection, DbTransaction transaction, Action, int> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { if (string.IsNullOrEmpty(cmdText)) return; var dt = DateTime.Now; @@ -586,7 +586,7 @@ namespace FreeSql.Internal.CommonProvider LoggerException(pool, pc, new Exception($"连接失败,准备切换其他可用服务器"), dt, logtxt, false); pc.cmd.Parameters.Clear(); if (DataType == DataType.Sqlite) pc.cmd.Dispose(); - ExecuteReaderMultiple(multipleResult, connection, transaction, readerHander, cmdType, cmdText, cmdParms); + ExecuteReaderMultiple(multipleResult, connection, transaction, fetchHandler, cmdType, cmdText, cmdParms); return; } } @@ -603,6 +603,7 @@ namespace FreeSql.Internal.CommonProvider using (var dr = pc.cmd.ExecuteReader()) { int resultIndex = 0; + var fetch = new FetchCallbackArgs { Object = dr }; while (true) { while (true) @@ -610,8 +611,15 @@ namespace FreeSql.Internal.CommonProvider bool isread = dr.Read(); if (isread == false) break; - if (readerHander != null) - readerHander(dr, resultIndex); + if (fetchHandler != null) + { + fetchHandler(fetch, resultIndex); + if (fetch.IsBreak) + { + resultIndex = multipleResult; + break; + } + } } if (++resultIndex >= multipleResult || dr.NextResult() == false) break; } @@ -649,10 +657,10 @@ namespace FreeSql.Internal.CommonProvider public object[][] ExecuteArray(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { List ret = new List(); - ExecuteReader(connection, transaction, dr => + ExecuteReader(connection, transaction, fetch => { - object[] values = new object[dr.FieldCount]; - dr.GetValues(values); + object[] values = new object[fetch.Object.FieldCount]; + fetch.Object.GetValues(values); ret.Add(values); }, cmdType, cmdText, cmdParms); return ret.ToArray(); @@ -666,20 +674,20 @@ namespace FreeSql.Internal.CommonProvider { var ret = new DataSet(); DataTable dt = null; - ExecuteReaderMultiple(16, connection, transaction, (dr, result) => + ExecuteReaderMultiple(16, connection, transaction, (fetch, result) => { if (ret.Tables.Count <= result) { dt = ret.Tables.Add(); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dt.Columns.Contains(name)) name = $"{name}_{Guid.NewGuid().ToString("N").Substring(0, 4)}"; - dt.Columns.Add(name, dr.GetFieldType(a)); + dt.Columns.Add(name, fetch.Object.GetFieldType(a)); } } object[] values = new object[dt.Columns.Count]; - dr.GetValues(values); + fetch.Object.GetValues(values); dt.Rows.Add(values); }, cmdType, cmdText, cmdParms); return ret; @@ -692,17 +700,17 @@ namespace FreeSql.Internal.CommonProvider public DataTable ExecuteDataTable(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { var ret = new DataTable(); - ExecuteReader(connection, transaction, dr => + ExecuteReader(connection, transaction, fetch => { if (ret.Columns.Count == 0) - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (ret.Columns.Contains(name)) name = $"{name}_{Guid.NewGuid().ToString("N").Substring(0, 4)}"; - ret.Columns.Add(name, dr.GetFieldType(a)); + ret.Columns.Add(name, fetch.Object.GetFieldType(a)); } object[] values = new object[ret.Columns.Count]; - dr.GetValues(values); + fetch.Object.GetValues(values); ret.Rows.Add(values); }, cmdType, cmdText, cmdParms); return ret; diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs index 92e873e3..612ff0b2 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs @@ -29,15 +29,15 @@ namespace FreeSql.Internal.CommonProvider string flag = null; int[] indexes = null; var props = GetQueryTypeProperties(type); - await ExecuteReaderAsync(connection, transaction, dr => + await ExecuteReaderAsync(connection, transaction, fetch => { if (indexes == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -45,7 +45,7 @@ namespace FreeSql.Internal.CommonProvider indexes = props.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag = sbflag.ToString(); } - ret.Add((T)Utils.ExecuteArrayRowReadClassOrTuple(flag, type, indexes, dr, 0, _util).Value); + ret.Add((T)Utils.ExecuteArrayRowReadClassOrTuple(flag, type, indexes, fetch.Object, 0, _util).Value); return Task.FromResult(false); }, cmdType, cmdText, cmdParms); return ret; @@ -70,7 +70,7 @@ namespace FreeSql.Internal.CommonProvider string flag2 = null; int[] indexes2 = null; var props2 = GetQueryTypeProperties(type2); - await ExecuteReaderMultipleAsync(2, connection, transaction, (dr, result) => + await ExecuteReaderMultipleAsync(2, connection, transaction, (fetch, result) => { switch (result) { @@ -79,9 +79,9 @@ namespace FreeSql.Internal.CommonProvider { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -89,16 +89,16 @@ namespace FreeSql.Internal.CommonProvider indexes1 = props1.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag1 = sbflag.ToString(); } - ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, dr, 0, _util).Value); + ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, fetch.Object, 0, _util).Value); break; case 1: if (indexes2 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -106,7 +106,7 @@ namespace FreeSql.Internal.CommonProvider indexes2 = props2.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag2 = sbflag.ToString(); } - ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, dr, 0, _util).Value); + ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, fetch.Object, 0, _util).Value); break; } return Task.FromResult(false); @@ -139,7 +139,7 @@ namespace FreeSql.Internal.CommonProvider string flag3 = null; int[] indexes3 = null; var props3 = GetQueryTypeProperties(type3); - await ExecuteReaderMultipleAsync(3, connection, transaction, (dr, result) => + await ExecuteReaderMultipleAsync(3, connection, transaction, (fetch, result) => { switch (result) { @@ -148,9 +148,9 @@ namespace FreeSql.Internal.CommonProvider { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -158,16 +158,16 @@ namespace FreeSql.Internal.CommonProvider indexes1 = props1.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag1 = sbflag.ToString(); } - ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, dr, 0, _util).Value); + ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, fetch.Object, 0, _util).Value); break; case 1: if (indexes2 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -175,16 +175,16 @@ namespace FreeSql.Internal.CommonProvider indexes2 = props2.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag2 = sbflag.ToString(); } - ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, dr, 0, _util).Value); + ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, fetch.Object, 0, _util).Value); break; case 2: if (indexes3 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -192,7 +192,7 @@ namespace FreeSql.Internal.CommonProvider indexes3 = props3.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag3 = sbflag.ToString(); } - ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, dr, 0, _util).Value); + ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, fetch.Object, 0, _util).Value); break; } return Task.FromResult(false); @@ -231,7 +231,7 @@ namespace FreeSql.Internal.CommonProvider string flag4 = null; int[] indexes4 = null; var props4 = GetQueryTypeProperties(type4); - await ExecuteReaderMultipleAsync(4, connection, transaction, (dr, result) => + await ExecuteReaderMultipleAsync(4, connection, transaction, (fetch, result) => { switch (result) { @@ -240,9 +240,9 @@ namespace FreeSql.Internal.CommonProvider { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -250,16 +250,16 @@ namespace FreeSql.Internal.CommonProvider indexes1 = props1.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag1 = sbflag.ToString(); } - ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, dr, 0, _util).Value); + ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, fetch.Object, 0, _util).Value); break; case 1: if (indexes2 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -267,16 +267,16 @@ namespace FreeSql.Internal.CommonProvider indexes2 = props2.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag2 = sbflag.ToString(); } - ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, dr, 0, _util).Value); + ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, fetch.Object, 0, _util).Value); break; case 2: if (indexes3 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -284,16 +284,16 @@ namespace FreeSql.Internal.CommonProvider indexes3 = props3.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag3 = sbflag.ToString(); } - ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, dr, 0, _util).Value); + ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, fetch.Object, 0, _util).Value); break; case 3: if (indexes4 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -301,7 +301,7 @@ namespace FreeSql.Internal.CommonProvider indexes4 = props4.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag4 = sbflag.ToString(); } - ret4.Add((T4)Utils.ExecuteArrayRowReadClassOrTuple(flag4, type4, indexes4, dr, 0, _util).Value); + ret4.Add((T4)Utils.ExecuteArrayRowReadClassOrTuple(flag4, type4, indexes4, fetch.Object, 0, _util).Value); break; } return Task.FromResult(false); @@ -346,7 +346,7 @@ namespace FreeSql.Internal.CommonProvider string flag5 = null; int[] indexes5 = null; var props5 = GetQueryTypeProperties(type5); - await ExecuteReaderMultipleAsync(5, connection, transaction, (dr, result) => + await ExecuteReaderMultipleAsync(5, connection, transaction, (fetch, result) => { switch (result) { @@ -355,9 +355,9 @@ namespace FreeSql.Internal.CommonProvider { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -365,16 +365,16 @@ namespace FreeSql.Internal.CommonProvider indexes1 = props1.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag1 = sbflag.ToString(); } - ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, dr, 0, _util).Value); + ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, fetch.Object, 0, _util).Value); break; case 1: if (indexes2 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -382,16 +382,16 @@ namespace FreeSql.Internal.CommonProvider indexes2 = props2.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag2 = sbflag.ToString(); } - ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, dr, 0, _util).Value); + ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, fetch.Object, 0, _util).Value); break; case 2: if (indexes3 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -399,16 +399,16 @@ namespace FreeSql.Internal.CommonProvider indexes3 = props3.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag3 = sbflag.ToString(); } - ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, dr, 0, _util).Value); + ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, fetch.Object, 0, _util).Value); break; case 3: if (indexes4 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -416,16 +416,16 @@ namespace FreeSql.Internal.CommonProvider indexes4 = props4.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag4 = sbflag.ToString(); } - ret4.Add((T4)Utils.ExecuteArrayRowReadClassOrTuple(flag4, type4, indexes4, dr, 0, _util).Value); + ret4.Add((T4)Utils.ExecuteArrayRowReadClassOrTuple(flag4, type4, indexes4, fetch.Object, 0, _util).Value); break; case 4: if (indexes5 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -433,7 +433,7 @@ namespace FreeSql.Internal.CommonProvider indexes5 = props5.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag5 = sbflag.ToString(); } - ret5.Add((T5)Utils.ExecuteArrayRowReadClassOrTuple(flag5, type5, indexes5, dr, 0, _util).Value); + ret5.Add((T5)Utils.ExecuteArrayRowReadClassOrTuple(flag5, type5, indexes5, fetch.Object, 0, _util).Value); break; } return Task.FromResult(false); @@ -442,13 +442,13 @@ namespace FreeSql.Internal.CommonProvider } #endregion - public Task ExecuteReaderAsync(Func readerHander, string cmdText, object parms = null) => ExecuteReaderAsync(null, null, readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteReaderAsync(DbTransaction transaction, Func readerHander, string cmdText, object parms = null) => ExecuteReaderAsync(null, transaction, readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func readerHander, string cmdText, object parms = null) => ExecuteReaderAsync(connection, transaction, readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteReaderAsync(Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderAsync(null, null, readerHander, cmdType, cmdText, cmdParms); - public Task ExecuteReaderAsync(DbTransaction transaction, Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderAsync(null, transaction, readerHander, cmdType, cmdText, cmdParms); - public Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderMultipleAsync(1, connection, transaction, (dr, result) => readerHander(dr), cmdType, cmdText, cmdParms); - async Task ExecuteReaderMultipleAsync(int multipleResult, DbConnection connection, DbTransaction transaction, Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public Task ExecuteReaderAsync(Func, Task> fetchHandler, string cmdText, object parms = null) => ExecuteReaderAsync(null, null, fetchHandler, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteReaderAsync(DbTransaction transaction, Func, Task> fetchHandler, string cmdText, object parms = null) => ExecuteReaderAsync(null, transaction, fetchHandler, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func, Task> fetchHandler, string cmdText, object parms = null) => ExecuteReaderAsync(connection, transaction, fetchHandler, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteReaderAsync(Func, Task> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderAsync(null, null, fetchHandler, cmdType, cmdText, cmdParms); + public Task ExecuteReaderAsync(DbTransaction transaction, Func, Task> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderAsync(null, transaction, fetchHandler, cmdType, cmdText, cmdParms); + public Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func, Task> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderMultipleAsync(1, connection, transaction, (fetch, result) => fetchHandler(fetch), cmdType, cmdText, cmdParms); + async Task ExecuteReaderMultipleAsync(int multipleResult, DbConnection connection, DbTransaction transaction, Func, int, Task> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { if (string.IsNullOrEmpty(cmdText)) return; var dt = DateTime.Now; @@ -511,7 +511,7 @@ namespace FreeSql.Internal.CommonProvider LoggerException(pool, pc, new Exception($"连接失败,准备切换其他可用服务器"), dt, logtxt, false); pc.cmd.Parameters.Clear(); if (DataType == DataType.Sqlite) pc.cmd.Dispose(); - await ExecuteReaderMultipleAsync(multipleResult, connection, transaction, readerHander, cmdType, cmdText, cmdParms); + await ExecuteReaderMultipleAsync(multipleResult, connection, transaction, fetchHandler, cmdType, cmdText, cmdParms); return; } } @@ -528,6 +528,7 @@ namespace FreeSql.Internal.CommonProvider using (var dr = await pc.cmd.ExecuteReaderAsync()) { int resultIndex = 0; + var fetch = new FetchCallbackArgs { Object = dr }; while (true) { while (true) @@ -535,8 +536,15 @@ namespace FreeSql.Internal.CommonProvider bool isread = await dr.ReadAsync(); if (isread == false) break; - if (readerHander != null) - await readerHander(dr, resultIndex); + if (fetchHandler != null) + { + await fetchHandler(fetch, resultIndex); + if (fetch.IsBreak) + { + resultIndex = multipleResult; + break; + } + } } if (++resultIndex >= multipleResult || dr.NextResult() == false) break; } @@ -571,10 +579,10 @@ namespace FreeSql.Internal.CommonProvider async public Task ExecuteArrayAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { List ret = new List(); - await ExecuteReaderAsync(connection, transaction, async dr => + await ExecuteReaderAsync(connection, transaction, async fetch => { - object[] values = new object[dr.FieldCount]; - for (int a = 0; a < values.Length; a++) if (!await dr.IsDBNullAsync(a)) values[a] = await dr.GetFieldValueAsync(a); + object[] values = new object[fetch.Object.FieldCount]; + for (int a = 0; a < values.Length; a++) if (!await fetch.Object.IsDBNullAsync(a)) values[a] = await fetch.Object.GetFieldValueAsync(a); ret.Add(values); }, cmdType, cmdText, cmdParms); return ret.ToArray(); @@ -589,20 +597,20 @@ namespace FreeSql.Internal.CommonProvider { var ret = new DataSet(); DataTable dt = null; - await ExecuteReaderMultipleAsync(16, connection, transaction, async (dr, result) => + await ExecuteReaderMultipleAsync(16, connection, transaction, async (fetch, result) => { if (ret.Tables.Count <= result) { dt = ret.Tables.Add(); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dt.Columns.Contains(name)) name = $"{name}_{Guid.NewGuid().ToString("N").Substring(0, 4)}"; - dt.Columns.Add(name, dr.GetFieldType(a)); + dt.Columns.Add(name, fetch.Object.GetFieldType(a)); } } object[] values = new object[dt.Columns.Count]; - for (int a = 0; a < values.Length; a++) if (!await dr.IsDBNullAsync(a)) values[a] = await dr.GetFieldValueAsync(a); + for (int a = 0; a < values.Length; a++) if (!await fetch.Object.IsDBNullAsync(a)) values[a] = await fetch.Object.GetFieldValueAsync(a); dt.Rows.Add(values); }, cmdType, cmdText, cmdParms); return ret; @@ -615,17 +623,17 @@ namespace FreeSql.Internal.CommonProvider async public Task ExecuteDataTableAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { var ret = new DataTable(); - await ExecuteReaderAsync(connection, transaction, async dr => + await ExecuteReaderAsync(connection, transaction, async fetch => { if (ret.Columns.Count == 0) - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (ret.Columns.Contains(name)) name = $"{name}_{Guid.NewGuid().ToString("N").Substring(0, 4)}"; - ret.Columns.Add(name, dr.GetFieldType(a)); + ret.Columns.Add(name, fetch.Object.GetFieldType(a)); } object[] values = new object[ret.Columns.Count]; - for (int a = 0; a < values.Length; a++) if (!await dr.IsDBNullAsync(a)) values[a] = await dr.GetFieldValueAsync(a); + for (int a = 0; a < values.Length; a++) if (!await fetch.Object.IsDBNullAsync(a)) values[a] = await fetch.Object.GetFieldValueAsync(a); ret.Rows.Add(values); }, cmdType, cmdText, cmdParms); return ret; diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 93982fd4..b223326c 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -341,9 +341,9 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - _orm.Ado.ExecuteReader(_connection, _transaction, dr => + _orm.Ado.ExecuteReader(_connection, _transaction, fetch => { - var read = Utils.ExecuteArrayRowReadClassOrTuple(flagStr, type, null, dr, 0, _commonUtils); + var read = Utils.ExecuteArrayRowReadClassOrTuple(flagStr, type, null, fetch.Object, 0, _commonUtils); ret.Add((TTuple)read.Value); }, CommandType.Text, sql, dbParms); } @@ -368,14 +368,14 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - _orm.Ado.ExecuteReader(_connection, _transaction, dr => + _orm.Ado.ExecuteReader(_connection, _transaction, fetch => { - ret.Add(af.Read(_orm, dr)); + ret.Add(af.Read(_orm, fetch.Object)); if (otherData != null) { var idx = af.FieldCount - 1; foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref idx, false, null)); + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref idx, false, null)); } }, CommandType.Text, sql, dbParms); } @@ -409,37 +409,37 @@ namespace FreeSql.Internal.CommonProvider return ToListAfPrivate(sql, af, otherData); } #region ToChunk - internal void ToListAfChunkPrivate(int chunkSize, Action> chunkDone, string sql, GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData) + internal void ToListAfChunkPrivate(int chunkSize, Action>> chunkDone, string sql, GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData) { var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - var ret = new List(); + var ret = new FetchCallbackArgs> { Object = new List() }; var retCount = 0; Exception exception = null; var checkDoneTimes = 0; try { - _orm.Ado.ExecuteReader(_connection, _transaction, dr => + _orm.Ado.ExecuteReader(_connection, _transaction, fetch => { - ret.Add(af.Read(_orm, dr)); + ret.Object.Add(af.Read(_orm, fetch.Object)); retCount++; if (otherData != null) { var idx = af.FieldCount - 1; foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref idx, false, null)); + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref idx, false, null)); } - if (chunkSize > 0 && chunkSize == ret.Count) + if (chunkSize > 0 && chunkSize == ret.Object.Count) { checkDoneTimes++; - foreach (var include in _includeToList) include?.Invoke(ret); - _trackToList?.Invoke(ret); + foreach (var include in _includeToList) include?.Invoke(ret.Object); + _trackToList?.Invoke(ret.Object); chunkDone(ret); - + fetch.IsBreak = ret.IsBreak; - ret.Clear(); + ret.Object.Clear(); if (otherData != null) foreach (var other in otherData) other.retlist.Clear(); @@ -456,14 +456,14 @@ namespace FreeSql.Internal.CommonProvider var after = new Aop.CurdAfterEventArgs(before, exception, retCount); _orm.Aop.CurdAfterHandler?.Invoke(this, after); } - if (ret.Any() || checkDoneTimes == 0) + if (ret.Object.Any() || checkDoneTimes == 0) { - foreach (var include in _includeToList) include?.Invoke(ret); - _trackToList?.Invoke(ret); + foreach (var include in _includeToList) include?.Invoke(ret.Object); + _trackToList?.Invoke(ret.Object); chunkDone(ret); } } - internal void ToListChunkPrivate(int chunkSize, Action> chunkDone, GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData) + internal void ToListChunkPrivate(int chunkSize, Action>> chunkDone, GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData) { string sql = null; if (otherData?.Length > 0) @@ -478,7 +478,7 @@ namespace FreeSql.Internal.CommonProvider ToListAfChunkPrivate(chunkSize, chunkDone, sql, af, otherData); } - public void ToChunk(int size, Action> done, bool includeNestedMembers = false) + public void ToChunk(int size, Action>> done, bool includeNestedMembers = false) { if (_selectExpression != null) throw new ArgumentException("Chunk 功能之前不可使用 Select"); this.ToListChunkPrivate(size, done, includeNestedMembers == false ? this.GetAllFieldExpressionTreeLevel2() : this.GetAllFieldExpressionTreeLevelAll(), null); @@ -498,9 +498,9 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - _orm.Ado.ExecuteReader(_connection, _transaction, dr => + _orm.Ado.ExecuteReader(_connection, _transaction, fetch => { - var item = af.Read(_orm, dr); + var item = af.Read(_orm, fetch.Object); ret.Add(keySelector(item), elementSelector(item)); }, CommandType.Text, sql, dbParms); } @@ -540,13 +540,13 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - _orm.Ado.ExecuteReader(_connection, _transaction, dr => + _orm.Ado.ExecuteReader(_connection, _transaction, fetch => { var index = -1; - ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index, false, null)); + ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, fetch.Object, ref index, false, null)); if (otherData != null) foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref index, false, null)); + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref index, false, null)); }, CommandType.Text, sql, dbParms); } catch (Exception ex) @@ -1373,9 +1373,9 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, dr => + await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, fetch => { - var read = Utils.ExecuteArrayRowReadClassOrTuple(flagStr, type, null, dr, 0, _commonUtils); + var read = Utils.ExecuteArrayRowReadClassOrTuple(flagStr, type, null, fetch.Object, 0, _commonUtils); ret.Add((TTuple)read.Value); return Task.FromResult(false); }, CommandType.Text, sql, dbParms); @@ -1402,14 +1402,14 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, dr => + await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, fetch => { - ret.Add(af.Read(_orm, dr)); + ret.Add(af.Read(_orm, fetch.Object)); if (otherData != null) { var idx = af.FieldCount - 1; foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref idx, false, null)); + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref idx, false, null)); } return Task.FromResult(false); }, CommandType.Text, sql, dbParms); @@ -1459,9 +1459,9 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, dr => + await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, fetch => { - var item = af.Read(_orm, dr); + var item = af.Read(_orm, fetch.Object); ret.Add(keySelector(item), elementSelector(item)); return Task.FromResult(false); }, CommandType.Text, sql, dbParms); @@ -1503,13 +1503,13 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, dr => + await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, fetch => { var index = -1; - ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index, false, null)); + ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, fetch.Object, ref index, false, null)); if (otherData != null) foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref index, false, null)); + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref index, false, null)); return Task.FromResult(false); }, CommandType.Text, sql, dbParms); } diff --git a/FreeSql/Internal/Model/FetchCallbackArgs.cs b/FreeSql/Internal/Model/FetchCallbackArgs.cs new file mode 100644 index 00000000..b7f4ccb9 --- /dev/null +++ b/FreeSql/Internal/Model/FetchCallbackArgs.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FreeSql.Internal.Model +{ + public class FetchCallbackArgs + { + public T Object { get; set; } + + /// + /// 是否放弃继续读取 + /// + public bool IsBreak { get; set; } + } +}