mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 09:15:27 +08:00 
			
		
		
		
	- 增加 ISelect.ToDataTable 系列方法;
- 增加 无参数化命令执行,可配置全局 ICodeFirst.IsNoneCommandParameter、或临时 IInsert/IUpdate.NoneParameter() 便于调试; - 关闭 自动同步结构功能,避免线上环境误操作; - 优化 IInsert 批量插入容易导致 values 过多、或参数化过多的问题,5个数据库均已优化;
This commit is contained in:
		@@ -1,21 +1,21 @@
 | 
				
			|||||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
					<Project Sdk="Microsoft.NET.Sdk">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <PropertyGroup>
 | 
						<PropertyGroup>
 | 
				
			||||||
    <TargetFramework>netstandard2.0</TargetFramework>
 | 
							<TargetFramework>netstandard2.0</TargetFramework>
 | 
				
			||||||
    <Version>0.3.14</Version>
 | 
							<Version>0.3.15</Version>
 | 
				
			||||||
    <Authors>YeXiangQin</Authors>
 | 
							<Authors>YeXiangQin</Authors>
 | 
				
			||||||
    <Description>FreeSql 通用仓库层实现,支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite,读写分离、分表分库。</Description>
 | 
							<Description>FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table.</Description>
 | 
				
			||||||
    <PackageProjectUrl>https://github.com/2881099/FreeSql</PackageProjectUrl>
 | 
							<PackageProjectUrl>https://github.com/2881099/FreeSql/wiki/Repository</PackageProjectUrl>
 | 
				
			||||||
    <PackageTags>FreeSql ORM Repository</PackageTags>
 | 
							<PackageTags>FreeSql ORM Repository</PackageTags>
 | 
				
			||||||
    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
 | 
							<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
 | 
				
			||||||
  </PropertyGroup>
 | 
						</PropertyGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <ItemGroup>
 | 
						<ItemGroup>
 | 
				
			||||||
    <PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.4.0" />
 | 
							<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.4.0" />
 | 
				
			||||||
  </ItemGroup>
 | 
						</ItemGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <ItemGroup>
 | 
						<ItemGroup>
 | 
				
			||||||
    <ProjectReference Include="..\FreeSql\FreeSql.csproj" />
 | 
							<ProjectReference Include="..\FreeSql\FreeSql.csproj" />
 | 
				
			||||||
  </ItemGroup>
 | 
						</ItemGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</Project>
 | 
					</Project>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -95,8 +95,8 @@ namespace FreeSql.Tests.MySql {
 | 
				
			|||||||
			Assert.Equal(1, g.mysql.Insert<Topic>().AppendData(items.First()).ExecuteAffrows());
 | 
								Assert.Equal(1, g.mysql.Insert<Topic>().AppendData(items.First()).ExecuteAffrows());
 | 
				
			||||||
			Assert.Equal(10, g.mysql.Insert<Topic>().AppendData(items).ExecuteAffrows());
 | 
								Assert.Equal(10, g.mysql.Insert<Topic>().AppendData(items).ExecuteAffrows());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList();
 | 
								//items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList();
 | 
				
			||||||
			Assert.Equal(9989, g.mysql.Insert<Topic>(items).ExecuteAffrows());
 | 
								//Assert.Equal(9989, g.mysql.Insert<Topic>(items).ExecuteAffrows());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var dt1 = select.Limit(10).ToDataTable();
 | 
								var dt1 = select.Limit(10).ToDataTable();
 | 
				
			||||||
			var dt2 = select.Limit(10).ToDataTable("id, 111222");
 | 
								var dt2 = select.Limit(10).ToDataTable("id, 111222");
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,16 +32,25 @@ namespace FreeSql.Tests.Oracle {
 | 
				
			|||||||
			public List<TestTypeInfo> Types { get; set; }
 | 
								public List<TestTypeInfo> Types { get; set; }
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							class TopicInserts {
 | 
				
			||||||
 | 
								public Guid Id { get; set; }
 | 
				
			||||||
 | 
								public int Clicks { get; set; }
 | 
				
			||||||
 | 
								public int TestTypeInfoGuid { get; set; }
 | 
				
			||||||
 | 
								public TestTypeInfo Type { get; set; }
 | 
				
			||||||
 | 
								public string Title { get; set; }
 | 
				
			||||||
 | 
								public DateTime CreateTime { get; set; }
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[Fact]
 | 
							[Fact]
 | 
				
			||||||
		public void ToDataTable() {
 | 
							public void ToDataTable() {
 | 
				
			||||||
			var items = new List<Topic>();
 | 
								var items = new List<TopicInserts>();
 | 
				
			||||||
			for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now });
 | 
								for (var a = 0; a < 11; a++) items.Add(new TopicInserts { Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			Assert.Equal(1, g.oracle.Insert<Topic>().AppendData(items.First()).ExecuteAffrows());
 | 
								//Assert.Equal(1, g.oracle.Insert<TopicInserts>().AppendData(items.First()).ExecuteAffrows());
 | 
				
			||||||
			Assert.Equal(10, g.oracle.Insert<Topic>().AppendData(items).ExecuteAffrows());
 | 
								Assert.Equal(11, g.oracle.Insert<TopicInserts>().AppendData(items).ExecuteAffrows());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList();
 | 
								//items = Enumerable.Range(0, 9989).Select(a => new TopicInserts { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList();
 | 
				
			||||||
			Assert.Equal(9989, g.oracle.Insert<Topic>(items).ExecuteAffrows());
 | 
								//Assert.Equal(9989, g.oracle.Insert<TopicInserts>(items).ExecuteAffrows());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var dt1 = select.Limit(10).ToDataTable();
 | 
								var dt1 = select.Limit(10).ToDataTable();
 | 
				
			||||||
			var dt2 = select.Limit(10).ToDataTable("id, 111222");
 | 
								var dt2 = select.Limit(10).ToDataTable("id, 111222");
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,6 +32,21 @@ namespace FreeSql.Tests.PostgreSQL {
 | 
				
			|||||||
			public List<TestTypeInfo> Types { get; set; }
 | 
								public List<TestTypeInfo> Types { get; set; }
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							[Fact]
 | 
				
			||||||
 | 
							public void ToDataTable() {
 | 
				
			||||||
 | 
								var items = new List<Topic>();
 | 
				
			||||||
 | 
								for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Assert.Single(g.pgsql.Insert<Topic>().AppendData(items.First()).ExecuteInserted());
 | 
				
			||||||
 | 
								Assert.Equal(10, g.pgsql.Insert<Topic>().AppendData(items).ExecuteInserted().Count);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								//items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList();
 | 
				
			||||||
 | 
								//Assert.Equal(9989, g.pgsql.Insert<Topic>(items).ExecuteAffrows());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								var dt1 = select.Limit(10).ToDataTable();
 | 
				
			||||||
 | 
								var dt2 = select.Limit(10).ToDataTable("id, 222");
 | 
				
			||||||
 | 
								var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now });
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		[Fact]
 | 
							[Fact]
 | 
				
			||||||
		public void ToList() {
 | 
							public void ToList() {
 | 
				
			||||||
			var t1 = g.pgsql.Select<TestInfo>().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql();
 | 
								var t1 = g.pgsql.Select<TestInfo>().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -69,7 +69,7 @@ namespace FreeSql.Tests.SqlServer {
 | 
				
			|||||||
			var item = g.sqlserver.Insert<Topic>(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteInserted();
 | 
								var item = g.sqlserver.Insert<Topic>(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteInserted();
 | 
				
			||||||
			Assert.Equal(item[0].Id, delete.Where(a => a.Id == item[0].Id).ExecuteDeleted()[0].Id);
 | 
								Assert.Equal(item[0].Id, delete.Where(a => a.Id == item[0].Id).ExecuteDeleted()[0].Id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var items = Enumerable.Range(0, 3001).Select(a => new Topic { Title = "xxxx" + a, CreateTime = DateTime.Now });
 | 
								var items = Enumerable.Range(0, 301).Select(a => new Topic { Title = "xxxx" + a, CreateTime = DateTime.Now });
 | 
				
			||||||
			var itemsInserted = g.sqlserver.Insert<Topic>(items).ExecuteInserted();
 | 
								var itemsInserted = g.sqlserver.Insert<Topic>(items).ExecuteInserted();
 | 
				
			||||||
			Assert.Equal(items.First().Title, itemsInserted[0].Title);
 | 
								Assert.Equal(items.First().Title, itemsInserted[0].Title);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,7 @@ namespace FreeSql.Tests.SqlServer {
 | 
				
			|||||||
			[Column(IsIdentity = true, IsPrimary = true)]
 | 
								[Column(IsIdentity = true, IsPrimary = true)]
 | 
				
			||||||
			public int Id { get; set; }
 | 
								public int Id { get; set; }
 | 
				
			||||||
			public int? Clicks { get; set; }
 | 
								public int? Clicks { get; set; }
 | 
				
			||||||
 | 
								public int TestTypeInfoGuid { get; set; }
 | 
				
			||||||
			public TestTypeInfo Type { get; set; }
 | 
								public TestTypeInfo Type { get; set; }
 | 
				
			||||||
			public string Title { get; set; }
 | 
								public string Title { get; set; }
 | 
				
			||||||
			public DateTime CreateTime { get; set; }
 | 
								public DateTime CreateTime { get; set; }
 | 
				
			||||||
@@ -24,16 +25,16 @@ namespace FreeSql.Tests.SqlServer {
 | 
				
			|||||||
			var items = new List<Topic>();
 | 
								var items = new List<Topic>();
 | 
				
			||||||
			for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now });
 | 
								for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var sql = insert.AppendData(items.First()).ToSql();
 | 
								var sql = insert.IgnoreColumns(a => a.TestTypeInfoGuid).AppendData(items.First()).ToSql();
 | 
				
			||||||
			Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title], [CreateTime]) VALUES(@Clicks0, @Title0, @CreateTime0)", sql);
 | 
								Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title], [CreateTime]) VALUES(@Clicks0, @Title0, @CreateTime0)", sql);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sql = insert.AppendData(items).ToSql();
 | 
								sql = insert.IgnoreColumns(a => a.TestTypeInfoGuid).AppendData(items).ToSql();
 | 
				
			||||||
			Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title], [CreateTime]) VALUES(@Clicks0, @Title0, @CreateTime0), (@Clicks1, @Title1, @CreateTime1), (@Clicks2, @Title2, @CreateTime2), (@Clicks3, @Title3, @CreateTime3), (@Clicks4, @Title4, @CreateTime4), (@Clicks5, @Title5, @CreateTime5), (@Clicks6, @Title6, @CreateTime6), (@Clicks7, @Title7, @CreateTime7), (@Clicks8, @Title8, @CreateTime8), (@Clicks9, @Title9, @CreateTime9)", sql);
 | 
								Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title], [CreateTime]) VALUES(@Clicks0, @Title0, @CreateTime0), (@Clicks1, @Title1, @CreateTime1), (@Clicks2, @Title2, @CreateTime2), (@Clicks3, @Title3, @CreateTime3), (@Clicks4, @Title4, @CreateTime4), (@Clicks5, @Title5, @CreateTime5), (@Clicks6, @Title6, @CreateTime6), (@Clicks7, @Title7, @CreateTime7), (@Clicks8, @Title8, @CreateTime8), (@Clicks9, @Title9, @CreateTime9)", sql);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql();
 | 
								sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql();
 | 
				
			||||||
			Assert.Equal("INSERT INTO [tb_topic]([Title]) VALUES(@Title0), (@Title1), (@Title2), (@Title3), (@Title4), (@Title5), (@Title6), (@Title7), (@Title8), (@Title9)", sql);
 | 
								Assert.Equal("INSERT INTO [tb_topic]([Title]) VALUES(@Title0), (@Title1), (@Title2), (@Title3), (@Title4), (@Title5), (@Title6), (@Title7), (@Title8), (@Title9)", sql);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql();
 | 
								sql = insert.IgnoreColumns(a => new { a.CreateTime, a.TestTypeInfoGuid }).AppendData(items).ToSql();
 | 
				
			||||||
			Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title]) VALUES(@Clicks0, @Title0), (@Clicks1, @Title1), (@Clicks2, @Title2), (@Clicks3, @Title3), (@Clicks4, @Title4), (@Clicks5, @Title5), (@Clicks6, @Title6), (@Clicks7, @Title7), (@Clicks8, @Title8), (@Clicks9, @Title9)", sql);
 | 
								Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title]) VALUES(@Clicks0, @Title0), (@Clicks1, @Title1), (@Clicks2, @Title2), (@Clicks3, @Title3), (@Clicks4, @Title4), (@Clicks5, @Title5), (@Clicks6, @Title6), (@Clicks7, @Title7), (@Clicks8, @Title8), (@Clicks9, @Title9)", sql);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -53,10 +54,10 @@ namespace FreeSql.Tests.SqlServer {
 | 
				
			|||||||
			var items = new List<Topic>();
 | 
								var items = new List<Topic>();
 | 
				
			||||||
			for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now });
 | 
								for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql();
 | 
								var sql = insert.AppendData(items).IgnoreColumns(a => new { a.CreateTime, a.TestTypeInfoGuid }).ToSql();
 | 
				
			||||||
			Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title]) VALUES(@Clicks0, @Title0), (@Clicks1, @Title1), (@Clicks2, @Title2), (@Clicks3, @Title3), (@Clicks4, @Title4), (@Clicks5, @Title5), (@Clicks6, @Title6), (@Clicks7, @Title7), (@Clicks8, @Title8), (@Clicks9, @Title9)", sql);
 | 
								Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title]) VALUES(@Clicks0, @Title0), (@Clicks1, @Title1), (@Clicks2, @Title2), (@Clicks3, @Title3), (@Clicks4, @Title4), (@Clicks5, @Title5), (@Clicks6, @Title6), (@Clicks7, @Title7), (@Clicks8, @Title8), (@Clicks9, @Title9)", sql);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql();
 | 
								sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime, a.TestTypeInfoGuid }).ToSql();
 | 
				
			||||||
			Assert.Equal("INSERT INTO [tb_topic]([Clicks]) VALUES(@Clicks0), (@Clicks1), (@Clicks2), (@Clicks3), (@Clicks4), (@Clicks5), (@Clicks6), (@Clicks7), (@Clicks8), (@Clicks9)", sql);
 | 
								Assert.Equal("INSERT INTO [tb_topic]([Clicks]) VALUES(@Clicks0), (@Clicks1), (@Clicks2), (@Clicks3), (@Clicks4), (@Clicks5), (@Clicks6), (@Clicks7), (@Clicks8), (@Clicks9)", sql);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		[Fact]
 | 
							[Fact]
 | 
				
			||||||
@@ -67,8 +68,8 @@ namespace FreeSql.Tests.SqlServer {
 | 
				
			|||||||
			Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows());
 | 
								Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows());
 | 
				
			||||||
			Assert.Equal(10, insert.AppendData(items).ExecuteAffrows());
 | 
								Assert.Equal(10, insert.AppendData(items).ExecuteAffrows());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList();
 | 
								//items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList();
 | 
				
			||||||
			Assert.Equal(9989, g.sqlserver.Insert<Topic>(items).ExecuteAffrows());
 | 
								//Assert.Equal(9989, g.sqlserver.Insert<Topic>(items).ExecuteAffrows());
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		[Fact]
 | 
							[Fact]
 | 
				
			||||||
		public void ExecuteIdentity() {
 | 
							public void ExecuteIdentity() {
 | 
				
			||||||
@@ -78,9 +79,9 @@ namespace FreeSql.Tests.SqlServer {
 | 
				
			|||||||
			Assert.NotEqual(0, insert.AppendData(items.First()).ExecuteIdentity());
 | 
								Assert.NotEqual(0, insert.AppendData(items.First()).ExecuteIdentity());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			items = Enumerable.Range(0, 9999).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList();
 | 
								//items = Enumerable.Range(0, 9999).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList();
 | 
				
			||||||
			var lastId = g.sqlite.Select<Topic>().Max(a => a.Id);
 | 
								//var lastId = g.sqlite.Select<Topic>().Max(a => a.Id);
 | 
				
			||||||
			Assert.NotEqual(lastId, g.sqlserver.Insert<Topic>(items).ExecuteIdentity());
 | 
								//Assert.NotEqual(lastId, g.sqlserver.Insert<Topic>(items).ExecuteIdentity());
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		[Fact]
 | 
							[Fact]
 | 
				
			||||||
		public void ExecuteInserted() {
 | 
							public void ExecuteInserted() {
 | 
				
			||||||
@@ -89,7 +90,7 @@ namespace FreeSql.Tests.SqlServer {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			var items2 = insert.AppendData(items).ExecuteInserted();
 | 
								var items2 = insert.AppendData(items).ExecuteInserted();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			items = Enumerable.Range(0, 9990).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList();
 | 
								items = Enumerable.Range(0, 90).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList();
 | 
				
			||||||
			var itemsInserted = g.sqlserver.Insert<Topic>(items).ExecuteInserted();
 | 
								var itemsInserted = g.sqlserver.Insert<Topic>(items).ExecuteInserted();
 | 
				
			||||||
			Assert.Equal(items.First().Title, itemsInserted.First().Title);
 | 
								Assert.Equal(items.First().Title, itemsInserted.First().Title);
 | 
				
			||||||
			Assert.Equal(items.Last().Title, itemsInserted.Last().Title);
 | 
								Assert.Equal(items.Last().Title, itemsInserted.Last().Title);
 | 
				
			||||||
@@ -100,28 +101,28 @@ namespace FreeSql.Tests.SqlServer {
 | 
				
			|||||||
			var items = new List<Topic>();
 | 
								var items = new List<Topic>();
 | 
				
			||||||
			for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now });
 | 
								for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var sql = insert.AppendData(items.First()).AsTable(a => "tb_topicAsTable").ToSql();
 | 
								var sql = insert.IgnoreColumns(a => a.TestTypeInfoGuid).AppendData(items.First()).AsTable(a => "tb_topicAsTable").ToSql();
 | 
				
			||||||
			Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title], [CreateTime]) VALUES(@Clicks0, @Title0, @CreateTime0)", sql);
 | 
								Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title], [CreateTime]) VALUES(@Clicks0, @Title0, @CreateTime0)", sql);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sql = insert.AppendData(items).AsTable(a => "tb_topicAsTable").ToSql();
 | 
								sql = insert.IgnoreColumns(a => a.TestTypeInfoGuid).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql();
 | 
				
			||||||
			Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title], [CreateTime]) VALUES(@Clicks0, @Title0, @CreateTime0), (@Clicks1, @Title1, @CreateTime1), (@Clicks2, @Title2, @CreateTime2), (@Clicks3, @Title3, @CreateTime3), (@Clicks4, @Title4, @CreateTime4), (@Clicks5, @Title5, @CreateTime5), (@Clicks6, @Title6, @CreateTime6), (@Clicks7, @Title7, @CreateTime7), (@Clicks8, @Title8, @CreateTime8), (@Clicks9, @Title9, @CreateTime9)", sql);
 | 
								Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title], [CreateTime]) VALUES(@Clicks0, @Title0, @CreateTime0), (@Clicks1, @Title1, @CreateTime1), (@Clicks2, @Title2, @CreateTime2), (@Clicks3, @Title3, @CreateTime3), (@Clicks4, @Title4, @CreateTime4), (@Clicks5, @Title5, @CreateTime5), (@Clicks6, @Title6, @CreateTime6), (@Clicks7, @Title7, @CreateTime7), (@Clicks8, @Title8, @CreateTime8), (@Clicks9, @Title9, @CreateTime9)", sql);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "tb_topicAsTable").ToSql();
 | 
								sql = insert.IgnoreColumns(a => a.TestTypeInfoGuid).AppendData(items).InsertColumns(a => a.Title).AsTable(a => "tb_topicAsTable").ToSql();
 | 
				
			||||||
			Assert.Equal("INSERT INTO [tb_topicAsTable]([Title]) VALUES(@Title0), (@Title1), (@Title2), (@Title3), (@Title4), (@Title5), (@Title6), (@Title7), (@Title8), (@Title9)", sql);
 | 
								Assert.Equal("INSERT INTO [tb_topicAsTable]([Title]) VALUES(@Title0), (@Title1), (@Title2), (@Title3), (@Title4), (@Title5), (@Title6), (@Title7), (@Title8), (@Title9)", sql);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "tb_topicAsTable").ToSql();
 | 
								sql = insert.IgnoreColumns(a => new { a.CreateTime, a.TestTypeInfoGuid }).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql();
 | 
				
			||||||
			Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title]) VALUES(@Clicks0, @Title0), (@Clicks1, @Title1), (@Clicks2, @Title2), (@Clicks3, @Title3), (@Clicks4, @Title4), (@Clicks5, @Title5), (@Clicks6, @Title6), (@Clicks7, @Title7), (@Clicks8, @Title8), (@Clicks9, @Title9)", sql);
 | 
								Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title]) VALUES(@Clicks0, @Title0), (@Clicks1, @Title1), (@Clicks2, @Title2), (@Clicks3, @Title3), (@Clicks4, @Title4), (@Clicks5, @Title5), (@Clicks6, @Title6), (@Clicks7, @Title7), (@Clicks8, @Title8), (@Clicks9, @Title9)", sql);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "tb_topicAsTable").ToSql();
 | 
								sql = insert.IgnoreColumns(a => new { a.Title, a.TestTypeInfoGuid }).InsertColumns(a => a.Title).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql();
 | 
				
			||||||
			Assert.Equal("INSERT INTO [tb_topicAsTable]([Title]) VALUES(@Title0), (@Title1), (@Title2), (@Title3), (@Title4), (@Title5), (@Title6), (@Title7), (@Title8), (@Title9)", sql);
 | 
								Assert.Equal("INSERT INTO [tb_topicAsTable]([Title]) VALUES(@Title0), (@Title1), (@Title2), (@Title3), (@Title4), (@Title5), (@Title6), (@Title7), (@Title8), (@Title9)", sql);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "tb_topicAsTable").ToSql();
 | 
								sql = insert.IgnoreColumns(a => a.TestTypeInfoGuid).AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "tb_topicAsTable").ToSql();
 | 
				
			||||||
			Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title]) VALUES(@Clicks0, @Title0), (@Clicks1, @Title1), (@Clicks2, @Title2), (@Clicks3, @Title3), (@Clicks4, @Title4), (@Clicks5, @Title5), (@Clicks6, @Title6), (@Clicks7, @Title7), (@Clicks8, @Title8), (@Clicks9, @Title9)", sql);
 | 
								Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title]) VALUES(@Clicks0, @Title0), (@Clicks1, @Title1), (@Clicks2, @Title2), (@Clicks3, @Title3), (@Clicks4, @Title4), (@Clicks5, @Title5), (@Clicks6, @Title6), (@Clicks7, @Title7), (@Clicks8, @Title8), (@Clicks9, @Title9)", sql);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "tb_topicAsTable").ToSql();
 | 
								sql = insert.IgnoreColumns(a => new { a.CreateTime, a.TestTypeInfoGuid }).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql();
 | 
				
			||||||
			Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title]) VALUES(@Clicks0, @Title0), (@Clicks1, @Title1), (@Clicks2, @Title2), (@Clicks3, @Title3), (@Clicks4, @Title4), (@Clicks5, @Title5), (@Clicks6, @Title6), (@Clicks7, @Title7), (@Clicks8, @Title8), (@Clicks9, @Title9)", sql);
 | 
								Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title]) VALUES(@Clicks0, @Title0), (@Clicks1, @Title1), (@Clicks2, @Title2), (@Clicks3, @Title3), (@Clicks4, @Title4), (@Clicks5, @Title5), (@Clicks6, @Title6), (@Clicks7, @Title7), (@Clicks8, @Title8), (@Clicks9, @Title9)", sql);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).AsTable(a => "tb_topicAsTable").ToSql();
 | 
								sql = insert.IgnoreColumns(a => new { a.CreateTime, a.Title, a.TestTypeInfoGuid }).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql();
 | 
				
			||||||
			Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks]) VALUES(@Clicks0), (@Clicks1), (@Clicks2), (@Clicks3), (@Clicks4), (@Clicks5), (@Clicks6), (@Clicks7), (@Clicks8), (@Clicks9)", sql);
 | 
								Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks]) VALUES(@Clicks0), (@Clicks1), (@Clicks2), (@Clicks3), (@Clicks4), (@Clicks5), (@Clicks6), (@Clicks7), (@Clicks8), (@Clicks9)", sql);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,7 +13,7 @@ namespace FreeSql.Tests.SqlServer {
 | 
				
			|||||||
		class Topic {
 | 
							class Topic {
 | 
				
			||||||
			[Column(IsIdentity = true, IsPrimary = true)]
 | 
								[Column(IsIdentity = true, IsPrimary = true)]
 | 
				
			||||||
			public int Id { get; set; }
 | 
								public int Id { get; set; }
 | 
				
			||||||
			public int Clicks { get; set; }
 | 
								public int? Clicks { get; set; }
 | 
				
			||||||
			public int TestTypeInfoGuid { get; set; }
 | 
								public int TestTypeInfoGuid { get; set; }
 | 
				
			||||||
			public TestTypeInfo Type { get; set; }
 | 
								public TestTypeInfo Type { get; set; }
 | 
				
			||||||
			public string Title { get; set; }
 | 
								public string Title { get; set; }
 | 
				
			||||||
@@ -490,7 +490,7 @@ namespace FreeSql.Tests.SqlServer {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		[Fact]
 | 
							[Fact]
 | 
				
			||||||
		public void ToAggregate() {
 | 
							public void ToAggregate() {
 | 
				
			||||||
			var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) });
 | 
								var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(Convert.ToInt64(a.Key.Id)), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) });
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		[Fact]
 | 
							[Fact]
 | 
				
			||||||
		public void OrderBy() {
 | 
							public void OrderBy() {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,6 +12,7 @@ namespace FreeSql.Tests.SqlServer {
 | 
				
			|||||||
			[Column(IsIdentity = true, IsPrimary = true)]
 | 
								[Column(IsIdentity = true, IsPrimary = true)]
 | 
				
			||||||
			public int Id { get; set; }
 | 
								public int Id { get; set; }
 | 
				
			||||||
			public int? Clicks { get; set; }
 | 
								public int? Clicks { get; set; }
 | 
				
			||||||
 | 
								public int TestTypeInfoGuid { get; set; }
 | 
				
			||||||
			public TestTypeInfo Type { get; set; }
 | 
								public TestTypeInfo Type { get; set; }
 | 
				
			||||||
			public string Title { get; set; }
 | 
								public string Title { get; set; }
 | 
				
			||||||
			public DateTime CreateTime { get; set; }
 | 
								public DateTime CreateTime { get; set; }
 | 
				
			||||||
@@ -28,24 +29,24 @@ namespace FreeSql.Tests.SqlServer {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		[Fact]
 | 
							[Fact]
 | 
				
			||||||
		public void SetSource() {
 | 
							public void SetSource() {
 | 
				
			||||||
			var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).ToSql().Replace("\r\n", "");
 | 
								var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => a.TestTypeInfoGuid).ToSql().Replace("\r\n", "");
 | 
				
			||||||
			Assert.Equal("UPDATE [tb_topic] SET [Clicks] = @p_0, [Title] = @p_1, [CreateTime] = @p_2 WHERE ([Id] = 1)", sql);
 | 
								Assert.Equal("UPDATE [tb_topic] SET [Clicks] = @p_0, [Title] = @p_1, [CreateTime] = @p_2 WHERE ([Id] = 1)", sql);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var items = new List<Topic>();
 | 
								var items = new List<Topic>();
 | 
				
			||||||
			for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 });
 | 
								for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sql = update.SetSource(items).ToSql().Replace("\r\n", "");
 | 
								sql = update.SetSource(items).IgnoreColumns(a => a.TestTypeInfoGuid).ToSql().Replace("\r\n", "");
 | 
				
			||||||
			Assert.Equal("UPDATE [tb_topic] SET [Clicks] = CASE [Id] WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END, [Title] = CASE [Id] WHEN 1 THEN @p_10 WHEN 2 THEN @p_11 WHEN 3 THEN @p_12 WHEN 4 THEN @p_13 WHEN 5 THEN @p_14 WHEN 6 THEN @p_15 WHEN 7 THEN @p_16 WHEN 8 THEN @p_17 WHEN 9 THEN @p_18 WHEN 10 THEN @p_19 END, [CreateTime] = CASE [Id] WHEN 1 THEN @p_20 WHEN 2 THEN @p_21 WHEN 3 THEN @p_22 WHEN 4 THEN @p_23 WHEN 5 THEN @p_24 WHEN 6 THEN @p_25 WHEN 7 THEN @p_26 WHEN 8 THEN @p_27 WHEN 9 THEN @p_28 WHEN 10 THEN @p_29 END WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql);
 | 
								Assert.Equal("UPDATE [tb_topic] SET [Clicks] = CASE [Id] WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END, [Title] = CASE [Id] WHEN 1 THEN @p_10 WHEN 2 THEN @p_11 WHEN 3 THEN @p_12 WHEN 4 THEN @p_13 WHEN 5 THEN @p_14 WHEN 6 THEN @p_15 WHEN 7 THEN @p_16 WHEN 8 THEN @p_17 WHEN 9 THEN @p_18 WHEN 10 THEN @p_19 END, [CreateTime] = CASE [Id] WHEN 1 THEN @p_20 WHEN 2 THEN @p_21 WHEN 3 THEN @p_22 WHEN 4 THEN @p_23 WHEN 5 THEN @p_24 WHEN 6 THEN @p_25 WHEN 7 THEN @p_26 WHEN 8 THEN @p_27 WHEN 9 THEN @p_28 WHEN 10 THEN @p_29 END WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", "");
 | 
								sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime, a.TestTypeInfoGuid }).ToSql().Replace("\r\n", "");
 | 
				
			||||||
			Assert.Equal("UPDATE [tb_topic] SET [Title] = CASE [Id] WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql);
 | 
								Assert.Equal("UPDATE [tb_topic] SET [Title] = CASE [Id] WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sql = update.SetSource(items).Set(a => a.CreateTime, new DateTime(2020,1,1)).ToSql().Replace("\r\n", "");
 | 
								sql = update.SetSource(items).IgnoreColumns(a => a.TestTypeInfoGuid).Set(a => a.CreateTime, new DateTime(2020,1,1)).ToSql().Replace("\r\n", "");
 | 
				
			||||||
			Assert.Equal("UPDATE [tb_topic] SET [CreateTime] = @p_0 WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql);
 | 
								Assert.Equal("UPDATE [tb_topic] SET [CreateTime] = @p_0 WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		[Fact]
 | 
							[Fact]
 | 
				
			||||||
		public void IgnoreColumns() {
 | 
							public void IgnoreColumns() {
 | 
				
			||||||
			var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", "");
 | 
								var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime, a.TestTypeInfoGuid }).ToSql().Replace("\r\n", "");
 | 
				
			||||||
			Assert.Equal("UPDATE [tb_topic] SET [Title] = @p_0 WHERE ([Id] = 1)", sql);
 | 
								Assert.Equal("UPDATE [tb_topic] SET [Title] = @p_0 WHERE ([Id] = 1)", sql);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		[Fact]
 | 
							[Fact]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -81,8 +81,8 @@ namespace FreeSql.Tests.Sqlite {
 | 
				
			|||||||
			Assert.Equal(1, g.sqlite.Insert<Topic>().AppendData(items.First()).ExecuteAffrows());
 | 
								Assert.Equal(1, g.sqlite.Insert<Topic>().AppendData(items.First()).ExecuteAffrows());
 | 
				
			||||||
			Assert.Equal(10, g.sqlite.Insert<Topic>().AppendData(items).ExecuteAffrows());
 | 
								Assert.Equal(10, g.sqlite.Insert<Topic>().AppendData(items).ExecuteAffrows());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList();
 | 
								//items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList();
 | 
				
			||||||
			Assert.Equal(9989, g.sqlite.Insert<Topic>(items).ExecuteAffrows());
 | 
								//Assert.Equal(9989, g.sqlite.Insert<Topic>(items).ExecuteAffrows());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var dt1 = select.Limit(10).ToDataTable();
 | 
								var dt1 = select.Limit(10).ToDataTable();
 | 
				
			||||||
			var dt2 = select.Limit(10).ToDataTable("id, 111222");
 | 
								var dt2 = select.Limit(10).ToDataTable("id, 111222");
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,6 +12,7 @@ namespace FreeSql.Tests.Sqlite {
 | 
				
			|||||||
			[Column(IsIdentity = true, IsPrimary = true)]
 | 
								[Column(IsIdentity = true, IsPrimary = true)]
 | 
				
			||||||
			public int Id { get; set; }
 | 
								public int Id { get; set; }
 | 
				
			||||||
			public int? Clicks { get; set; }
 | 
								public int? Clicks { get; set; }
 | 
				
			||||||
 | 
								public int TestTypeInfoGuid { get; set; }
 | 
				
			||||||
			public TestTypeInfo Type { get; set; }
 | 
								public TestTypeInfo Type { get; set; }
 | 
				
			||||||
			public string Title { get; set; }
 | 
								public string Title { get; set; }
 | 
				
			||||||
			public DateTime CreateTime { get; set; }
 | 
								public DateTime CreateTime { get; set; }
 | 
				
			||||||
@@ -28,24 +29,24 @@ namespace FreeSql.Tests.Sqlite {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		[Fact]
 | 
							[Fact]
 | 
				
			||||||
		public void SetSource() {
 | 
							public void SetSource() {
 | 
				
			||||||
			var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).ToSql().Replace("\r\n", "");
 | 
								var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => a.TestTypeInfoGuid).ToSql().Replace("\r\n", "");
 | 
				
			||||||
			Assert.Equal("UPDATE \"tb_topic\" SET \"Clicks\" = @p_0, \"Title\" = @p_1, \"CreateTime\" = @p_2 WHERE (\"Id\" = 1)", sql);
 | 
								Assert.Equal("UPDATE \"tb_topic\" SET \"Clicks\" = @p_0, \"Title\" = @p_1, \"CreateTime\" = @p_2 WHERE (\"Id\" = 1)", sql);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var items = new List<Topic>();
 | 
								var items = new List<Topic>();
 | 
				
			||||||
			for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 });
 | 
								for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sql = update.SetSource(items).ToSql().Replace("\r\n", "");
 | 
								sql = update.SetSource(items).IgnoreColumns(a => a.TestTypeInfoGuid).ToSql().Replace("\r\n", "");
 | 
				
			||||||
			Assert.Equal("UPDATE \"tb_topic\" SET \"Clicks\" = CASE \"Id\" WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END, \"Title\" = CASE \"Id\" WHEN 1 THEN @p_10 WHEN 2 THEN @p_11 WHEN 3 THEN @p_12 WHEN 4 THEN @p_13 WHEN 5 THEN @p_14 WHEN 6 THEN @p_15 WHEN 7 THEN @p_16 WHEN 8 THEN @p_17 WHEN 9 THEN @p_18 WHEN 10 THEN @p_19 END, \"CreateTime\" = CASE \"Id\" WHEN 1 THEN @p_20 WHEN 2 THEN @p_21 WHEN 3 THEN @p_22 WHEN 4 THEN @p_23 WHEN 5 THEN @p_24 WHEN 6 THEN @p_25 WHEN 7 THEN @p_26 WHEN 8 THEN @p_27 WHEN 9 THEN @p_28 WHEN 10 THEN @p_29 END WHERE (\"Id\" IN (1,2,3,4,5,6,7,8,9,10))", sql);
 | 
								Assert.Equal("UPDATE \"tb_topic\" SET \"Clicks\" = CASE \"Id\" WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END, \"Title\" = CASE \"Id\" WHEN 1 THEN @p_10 WHEN 2 THEN @p_11 WHEN 3 THEN @p_12 WHEN 4 THEN @p_13 WHEN 5 THEN @p_14 WHEN 6 THEN @p_15 WHEN 7 THEN @p_16 WHEN 8 THEN @p_17 WHEN 9 THEN @p_18 WHEN 10 THEN @p_19 END, \"CreateTime\" = CASE \"Id\" WHEN 1 THEN @p_20 WHEN 2 THEN @p_21 WHEN 3 THEN @p_22 WHEN 4 THEN @p_23 WHEN 5 THEN @p_24 WHEN 6 THEN @p_25 WHEN 7 THEN @p_26 WHEN 8 THEN @p_27 WHEN 9 THEN @p_28 WHEN 10 THEN @p_29 END WHERE (\"Id\" IN (1,2,3,4,5,6,7,8,9,10))", sql);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", "");
 | 
								sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime, a.TestTypeInfoGuid }).ToSql().Replace("\r\n", "");
 | 
				
			||||||
			Assert.Equal("UPDATE \"tb_topic\" SET \"Title\" = CASE \"Id\" WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END WHERE (\"Id\" IN (1,2,3,4,5,6,7,8,9,10))", sql);
 | 
								Assert.Equal("UPDATE \"tb_topic\" SET \"Title\" = CASE \"Id\" WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END WHERE (\"Id\" IN (1,2,3,4,5,6,7,8,9,10))", sql);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sql = update.SetSource(items).Set(a => a.CreateTime, new DateTime(2020,1,1)).ToSql().Replace("\r\n", "");
 | 
								sql = update.SetSource(items).IgnoreColumns(a => a.TestTypeInfoGuid).Set(a => a.CreateTime, new DateTime(2020,1,1)).ToSql().Replace("\r\n", "");
 | 
				
			||||||
			Assert.Equal("UPDATE \"tb_topic\" SET \"CreateTime\" = @p_0 WHERE (\"Id\" IN (1,2,3,4,5,6,7,8,9,10))", sql);
 | 
								Assert.Equal("UPDATE \"tb_topic\" SET \"CreateTime\" = @p_0 WHERE (\"Id\" IN (1,2,3,4,5,6,7,8,9,10))", sql);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		[Fact]
 | 
							[Fact]
 | 
				
			||||||
		public void IgnoreColumns() {
 | 
							public void IgnoreColumns() {
 | 
				
			||||||
			var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", "");
 | 
								var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime, a.TestTypeInfoGuid }).ToSql().Replace("\r\n", "");
 | 
				
			||||||
			Assert.Equal("UPDATE \"tb_topic\" SET \"Title\" = @p_0 WHERE (\"Id\" = 1)", sql);
 | 
								Assert.Equal("UPDATE \"tb_topic\" SET \"Title\" = @p_0 WHERE (\"Id\" = 1)", sql);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		[Fact]
 | 
							[Fact]
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										7
									
								
								FreeSql/DataType.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								FreeSql/DataType.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace FreeSql {
 | 
				
			||||||
 | 
						public enum DataType { MySql, SqlServer, PostgreSQL, Oracle, Sqlite }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,8 +1,6 @@
 | 
				
			|||||||
using NpgsqlTypes;
 | 
					using System;
 | 
				
			||||||
using System;
 | 
					 | 
				
			||||||
using System.Collections;
 | 
					 | 
				
			||||||
using System.Collections.Generic;
 | 
					 | 
				
			||||||
using System.Collections.Concurrent;
 | 
					using System.Collections.Concurrent;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.ComponentModel;
 | 
					using System.ComponentModel;
 | 
				
			||||||
using System.Data;
 | 
					using System.Data;
 | 
				
			||||||
using System.Drawing;
 | 
					using System.Drawing;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,43 +0,0 @@
 | 
				
			|||||||
public static class FreeSqlStringExtensions {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	/// <param name="that"></param>
 | 
					 | 
				
			||||||
	/// <param name="args"></param>
 | 
					 | 
				
			||||||
	/// <returns></returns>
 | 
					 | 
				
			||||||
	public static string FormatMySql(this string that, params object[] args) => _mysqlAdo.Addslashes(that, args);
 | 
					 | 
				
			||||||
	static FreeSql.MySql.MySqlAdo _mysqlAdo = new FreeSql.MySql.MySqlAdo();
 | 
					 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	/// <param name="that"></param>
 | 
					 | 
				
			||||||
	/// <param name="args"></param>
 | 
					 | 
				
			||||||
	/// <returns></returns>
 | 
					 | 
				
			||||||
	public static string FormatSqlServer(this string that, params object[] args) => _sqlserverAdo.Addslashes(that, args);
 | 
					 | 
				
			||||||
	static FreeSql.SqlServer.SqlServerAdo _sqlserverAdo = new FreeSql.SqlServer.SqlServerAdo();
 | 
					 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	/// <param name="that"></param>
 | 
					 | 
				
			||||||
	/// <param name="args"></param>
 | 
					 | 
				
			||||||
	/// <returns></returns>
 | 
					 | 
				
			||||||
	public static string FormatPostgreSQL(this string that, params object[] args) => _postgresqlAdo.Addslashes(that, args);
 | 
					 | 
				
			||||||
	static FreeSql.PostgreSQL.PostgreSQLAdo _postgresqlAdo = new FreeSql.PostgreSQL.PostgreSQLAdo();
 | 
					 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	/// <param name="that"></param>
 | 
					 | 
				
			||||||
	/// <param name="args"></param>
 | 
					 | 
				
			||||||
	/// <returns></returns>
 | 
					 | 
				
			||||||
	public static string FormatOracleSQL(this string that, params object[] args) => _oracleAdo.Addslashes(that, args);
 | 
					 | 
				
			||||||
	static FreeSql.Oracle.OracleAdo _oracleAdo = new FreeSql.Oracle.OracleAdo();
 | 
					 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	/// <param name="that"></param>
 | 
					 | 
				
			||||||
	/// <param name="args"></param>
 | 
					 | 
				
			||||||
	/// <returns></returns>
 | 
					 | 
				
			||||||
	public static string FormatSqlite (this string that, params object[] args) => _sqliteAdo.Addslashes(that, args);
 | 
					 | 
				
			||||||
	static FreeSql.Sqlite.SqliteAdo _sqliteAdo = new FreeSql.Sqlite.SqliteAdo();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										44
									
								
								FreeSql/FreeSql.MySql.csproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								FreeSql/FreeSql.MySql.csproj
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
				
			|||||||
 | 
					<Project Sdk="Microsoft.NET.Sdk">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						<PropertyGroup>
 | 
				
			||||||
 | 
							<TargetFramework>netstandard2.0</TargetFramework>
 | 
				
			||||||
 | 
							<Version>0.3.14</Version>
 | 
				
			||||||
 | 
							<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
 | 
				
			||||||
 | 
							<Authors>YeXiangQin</Authors>
 | 
				
			||||||
 | 
							<Description>打造 .NETCore 最方便的 ORM,DbFirst 与 CodeFirst 混合使用,提供从实体同步数据库,或者从数据库生成实体代码,支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite,读写分离、分表分库。</Description>
 | 
				
			||||||
 | 
							<PackageProjectUrl>https://github.com/2881099/FreeSql</PackageProjectUrl>
 | 
				
			||||||
 | 
							<PackageTags>FreeSql ORM</PackageTags>
 | 
				
			||||||
 | 
						</PropertyGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						<ItemGroup>
 | 
				
			||||||
 | 
							<Compile Remove="Oracle\**" />
 | 
				
			||||||
 | 
							<Compile Remove="PostgreSQL\**" />
 | 
				
			||||||
 | 
							<Compile Remove="Sqlite\**" />
 | 
				
			||||||
 | 
							<Compile Remove="SqlServer\**" />
 | 
				
			||||||
 | 
							<EmbeddedResource Remove="Oracle\**" />
 | 
				
			||||||
 | 
							<EmbeddedResource Remove="PostgreSQL\**" />
 | 
				
			||||||
 | 
							<EmbeddedResource Remove="Sqlite\**" />
 | 
				
			||||||
 | 
							<EmbeddedResource Remove="SqlServer\**" />
 | 
				
			||||||
 | 
							<None Remove="Oracle\**" />
 | 
				
			||||||
 | 
							<None Remove="PostgreSQL\**" />
 | 
				
			||||||
 | 
							<None Remove="Sqlite\**" />
 | 
				
			||||||
 | 
							<None Remove="SqlServer\**" />
 | 
				
			||||||
 | 
						</ItemGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						<ItemGroup>
 | 
				
			||||||
 | 
							<Compile Remove="FreeSqlBuilder.cs" />
 | 
				
			||||||
 | 
						</ItemGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						<ItemGroup>
 | 
				
			||||||
 | 
							<PackageReference Include="CS-Script.Core" Version="1.0.6" />
 | 
				
			||||||
 | 
							<PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
 | 
				
			||||||
 | 
							<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="2.1.0" />
 | 
				
			||||||
 | 
							<PackageReference Include="Microsoft.Extensions.Logging" Version="2.1.0" />
 | 
				
			||||||
 | 
							<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.1.0" />
 | 
				
			||||||
 | 
							<PackageReference Include="MySql.Data" Version="8.0.15" />
 | 
				
			||||||
 | 
							<PackageReference Include="Npgsql.LegacyPostgis" Version="4.0.5" />
 | 
				
			||||||
 | 
							<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
 | 
				
			||||||
 | 
							<PackageReference Include="SafeObjectPool" Version="2.0.1" />
 | 
				
			||||||
 | 
						</ItemGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</Project>
 | 
				
			||||||
@@ -1,30 +1,28 @@
 | 
				
			|||||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
					<Project Sdk="Microsoft.NET.Sdk">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <PropertyGroup>
 | 
						<PropertyGroup>
 | 
				
			||||||
    <TargetFramework>netstandard2.0</TargetFramework>
 | 
							<TargetFramework>netstandard2.0</TargetFramework>
 | 
				
			||||||
    <Version>0.3.14</Version>
 | 
							<Version>0.3.15</Version>
 | 
				
			||||||
    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
 | 
							<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
 | 
				
			||||||
    <Authors>YeXiangQin</Authors>
 | 
							<Authors>YeXiangQin</Authors>
 | 
				
			||||||
    <Description>打造 .NETCore 最方便的 ORM,DbFirst 与 CodeFirst 混合使用,提供从实体同步数据库,或者从数据库生成实体代码,支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite,读写分离、分表分库。</Description>
 | 
							<Description>FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite.</Description>
 | 
				
			||||||
    <PackageProjectUrl>https://github.com/2881099/FreeSql</PackageProjectUrl>
 | 
							<PackageProjectUrl>https://github.com/2881099/FreeSql</PackageProjectUrl>
 | 
				
			||||||
    <PackageTags>FreeSql ORM</PackageTags>
 | 
							<PackageTags>FreeSql ORM</PackageTags>
 | 
				
			||||||
  </PropertyGroup>
 | 
						</PropertyGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <ItemGroup>
 | 
						<ItemGroup>
 | 
				
			||||||
    <PackageReference Include="CS-Script.Core" Version="1.0.6" />
 | 
							<PackageReference Include="CS-Script.Core" Version="1.0.6" />
 | 
				
			||||||
    <PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
 | 
							<PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
 | 
				
			||||||
    <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="2.1.0" />
 | 
							<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="2.1.0" />
 | 
				
			||||||
    <PackageReference Include="Microsoft.Extensions.Logging" Version="2.1.0" />
 | 
							<PackageReference Include="Microsoft.Extensions.Logging" Version="2.1.0" />
 | 
				
			||||||
    <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.1.0" />
 | 
							<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.1.0" />
 | 
				
			||||||
    <PackageReference Include="MySql.Data" Version="8.0.15" />
 | 
							<PackageReference Include="MySql.Data" Version="8.0.15" />
 | 
				
			||||||
    <PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
 | 
							<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
 | 
				
			||||||
    <PackageReference Include="Npgsql" Version="4.0.5" />
 | 
							<PackageReference Include="Npgsql.LegacyPostgis" Version="4.0.5" />
 | 
				
			||||||
    <PackageReference Include="Npgsql.LegacyPostgis" Version="4.0.5" />
 | 
							<PackageReference Include="Oracle.ManagedDataAccess.Core" Version="2.18.5" />
 | 
				
			||||||
    <PackageReference Include="Oracle.ManagedDataAccess.Core" Version="2.18.5" />
 | 
							<PackageReference Include="SafeObjectPool" Version="2.0.1" />
 | 
				
			||||||
    <PackageReference Include="SafeObjectPool" Version="2.0.1" />
 | 
							<PackageReference Include="System.Data.SqlClient" Version="4.6.0" />
 | 
				
			||||||
    <PackageReference Include="System.Data.SqlClient" Version="4.6.0" />
 | 
							<PackageReference Include="System.Data.SQLite.Core" Version="1.0.110" />
 | 
				
			||||||
    <PackageReference Include="System.Data.SQLite.Core" Version="1.0.110" />
 | 
						</ItemGroup>
 | 
				
			||||||
    <PackageReference Include="System.Reflection.Emit.Lightweight" Version="4.3.0" />
 | 
					 | 
				
			||||||
  </ItemGroup>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
</Project>
 | 
					</Project>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,7 @@
 | 
				
			|||||||
using Microsoft.Extensions.Caching.Distributed;
 | 
					using Microsoft.Extensions.Caching.Distributed;
 | 
				
			||||||
using Microsoft.Extensions.Logging;
 | 
					using Microsoft.Extensions.Logging;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					 | 
				
			||||||
using System.Data.Common;
 | 
					using System.Data.Common;
 | 
				
			||||||
using System.Text;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace FreeSql {
 | 
					namespace FreeSql {
 | 
				
			||||||
	public class FreeSqlBuilder {
 | 
						public class FreeSqlBuilder {
 | 
				
			||||||
@@ -16,6 +14,7 @@ namespace FreeSql {
 | 
				
			|||||||
		bool _isSyncStructureToLower = false;
 | 
							bool _isSyncStructureToLower = false;
 | 
				
			||||||
		bool _isSyncStructureToUpper = false;
 | 
							bool _isSyncStructureToUpper = false;
 | 
				
			||||||
		bool _isConfigEntityFromDbFirst = false;
 | 
							bool _isConfigEntityFromDbFirst = false;
 | 
				
			||||||
 | 
							bool _isNoneCommandParameter = false;
 | 
				
			||||||
		bool _isLazyLoading = false;
 | 
							bool _isLazyLoading = false;
 | 
				
			||||||
		Action<DbCommand> _aopCommandExecuting = null;
 | 
							Action<DbCommand> _aopCommandExecuting = null;
 | 
				
			||||||
		Action<DbCommand, string> _aopCommandExecuted = null;
 | 
							Action<DbCommand, string> _aopCommandExecuted = null;
 | 
				
			||||||
@@ -96,6 +95,15 @@ namespace FreeSql {
 | 
				
			|||||||
			return this;
 | 
								return this;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// 不使用命令参数化执行,针对 Insert/Update,也可临时使用 IInsert/IUpdate.NoneParameter() 
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							/// <param name="value"></param>
 | 
				
			||||||
 | 
							/// <returns></returns>
 | 
				
			||||||
 | 
							public FreeSqlBuilder UseNoneCommandParameter(bool value) {
 | 
				
			||||||
 | 
								_isNoneCommandParameter = value;
 | 
				
			||||||
 | 
								return this;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
		/// 延时加载导航属性对象,导航属性需要声明 virtual
 | 
							/// 延时加载导航属性对象,导航属性需要声明 virtual
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		/// <param name="value"></param>
 | 
							/// <param name="value"></param>
 | 
				
			||||||
@@ -131,6 +139,7 @@ namespace FreeSql {
 | 
				
			|||||||
				ret.CodeFirst.IsSyncStructureToLower = _isSyncStructureToLower;
 | 
									ret.CodeFirst.IsSyncStructureToLower = _isSyncStructureToLower;
 | 
				
			||||||
				ret.CodeFirst.IsSyncStructureToUpper = _isSyncStructureToUpper;
 | 
									ret.CodeFirst.IsSyncStructureToUpper = _isSyncStructureToUpper;
 | 
				
			||||||
				ret.CodeFirst.IsConfigEntityFromDbFirst = _isConfigEntityFromDbFirst;
 | 
									ret.CodeFirst.IsConfigEntityFromDbFirst = _isConfigEntityFromDbFirst;
 | 
				
			||||||
 | 
									ret.CodeFirst.IsNoneCommandParameter = _isNoneCommandParameter;
 | 
				
			||||||
				ret.CodeFirst.IsLazyLoading = _isLazyLoading;
 | 
									ret.CodeFirst.IsLazyLoading = _isLazyLoading;
 | 
				
			||||||
				var ado = ret.Ado as Internal.CommonProvider.AdoProvider;
 | 
									var ado = ret.Ado as Internal.CommonProvider.AdoProvider;
 | 
				
			||||||
				ado.AopCommandExecuting += _aopCommandExecuting;
 | 
									ado.AopCommandExecuting += _aopCommandExecuting;
 | 
				
			||||||
@@ -139,6 +148,4 @@ namespace FreeSql {
 | 
				
			|||||||
			return ret;
 | 
								return ret;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	public enum DataType { MySql, SqlServer, PostgreSQL, Oracle, Sqlite }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +1,5 @@
 | 
				
			|||||||
using NpgsqlTypes;
 | 
					using System;
 | 
				
			||||||
using System;
 | 
					 | 
				
			||||||
using System.Collections;
 | 
					 | 
				
			||||||
using System.Collections.Generic;
 | 
					 | 
				
			||||||
using System.Diagnostics;
 | 
					using System.Diagnostics;
 | 
				
			||||||
using System.Linq;
 | 
					 | 
				
			||||||
using System.Text;
 | 
					 | 
				
			||||||
using System.Threading;
 | 
					using System.Threading;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public static class FreeUtil {
 | 
					public static class FreeUtil {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -40,6 +40,12 @@ namespace FreeSql {
 | 
				
			|||||||
		/// <returns></returns>
 | 
							/// <returns></returns>
 | 
				
			||||||
		IInsert<T1> IgnoreColumns(Expression<Func<T1, object>> columns);
 | 
							IInsert<T1> IgnoreColumns(Expression<Func<T1, object>> columns);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// 不使用参数化,可通过 IFreeSql.CodeFirst.IsNotCommandParameter 全局性设置
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							/// <returns></returns>
 | 
				
			||||||
 | 
							IInsert<T1> NoneParameter();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名;
 | 
							/// 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名;
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,12 @@ namespace FreeSql {
 | 
				
			|||||||
		/// <returns></returns>
 | 
							/// <returns></returns>
 | 
				
			||||||
		IUpdate<T1> WithTransaction(DbTransaction transaction);
 | 
							IUpdate<T1> WithTransaction(DbTransaction transaction);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// 不使用参数化,可通过 IFreeSql.CodeFirst.IsNotCommandParameter 全局性设置
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							/// <returns></returns>
 | 
				
			||||||
 | 
							IUpdate<T1> NoneParameter();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// 更新数据,设置更新的实体
 | 
							/// 更新数据,设置更新的实体
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,6 +22,10 @@ namespace FreeSql {
 | 
				
			|||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		bool IsConfigEntityFromDbFirst { get; set; }
 | 
							bool IsConfigEntityFromDbFirst { get; set; }
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// 不使用命令参数化执行,针对 Insert/Update
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							bool IsNoneCommandParameter { get; set; }
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
		/// 延时加载导航属性对象,导航属性需要声明 virtual
 | 
							/// 延时加载导航属性对象,导航属性需要声明 virtual
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		bool IsLazyLoading { get; set; }
 | 
							bool IsLazyLoading { get; set; }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,5 @@
 | 
				
			|||||||
using FreeSql.Internal.Model;
 | 
					using FreeSql.Internal.Model;
 | 
				
			||||||
 | 
					using SafeObjectPool;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Data;
 | 
					using System.Data;
 | 
				
			||||||
@@ -18,6 +19,7 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
		protected Dictionary<string, bool> _ignore = new Dictionary<string, bool>(StringComparer.CurrentCultureIgnoreCase);
 | 
							protected Dictionary<string, bool> _ignore = new Dictionary<string, bool>(StringComparer.CurrentCultureIgnoreCase);
 | 
				
			||||||
		protected TableInfo _table;
 | 
							protected TableInfo _table;
 | 
				
			||||||
		protected Func<string, string> _tableRule;
 | 
							protected Func<string, string> _tableRule;
 | 
				
			||||||
 | 
							protected bool _noneParameter;
 | 
				
			||||||
		protected DbParameter[] _params;
 | 
							protected DbParameter[] _params;
 | 
				
			||||||
		protected DbTransaction _transaction;
 | 
							protected DbTransaction _transaction;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -26,6 +28,7 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
			_commonUtils = commonUtils;
 | 
								_commonUtils = commonUtils;
 | 
				
			||||||
			_commonExpression = commonExpression;
 | 
								_commonExpression = commonExpression;
 | 
				
			||||||
			_table = _commonUtils.GetTableByEntity(typeof(T1));
 | 
								_table = _commonUtils.GetTableByEntity(typeof(T1));
 | 
				
			||||||
 | 
								_noneParameter = _orm.CodeFirst.IsNoneCommandParameter;
 | 
				
			||||||
			if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure<T1>();
 | 
								if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure<T1>();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -33,6 +36,10 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
			_transaction = transaction;
 | 
								_transaction = transaction;
 | 
				
			||||||
			return this;
 | 
								return this;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							public IInsert<T1> NoneParameter() {
 | 
				
			||||||
 | 
								_noneParameter = false;
 | 
				
			||||||
 | 
								return this;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public IInsert<T1> AppendData(T1 source) {
 | 
							public IInsert<T1> AppendData(T1 source) {
 | 
				
			||||||
			if (source != null) _source.Add(source);
 | 
								if (source != null) _source.Add(source);
 | 
				
			||||||
@@ -43,8 +50,228 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
			return this;
 | 
								return this;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public virtual int ExecuteAffrows() => _orm.Ado.ExecuteNonQuery(_transaction, CommandType.Text, this.ToSql(), _params);
 | 
							#region 参数化数据限制,或values数量限制
 | 
				
			||||||
		public virtual Task<int> ExecuteAffrowsAsync() => _orm.Ado.ExecuteNonQueryAsync(_transaction, CommandType.Text, this.ToSql(), _params);
 | 
							internal List<T1>[] SplitSource(int valuesLimit, int parameterLimit) {
 | 
				
			||||||
 | 
								valuesLimit = valuesLimit - 1;
 | 
				
			||||||
 | 
								parameterLimit = parameterLimit - 1;
 | 
				
			||||||
 | 
								if (_source == null || _source.Any() == false) return new List<T1>[0];
 | 
				
			||||||
 | 
								if (_source.Count == 1) return new[] { _source };
 | 
				
			||||||
 | 
								if (_noneParameter) {
 | 
				
			||||||
 | 
									if (_source.Count < valuesLimit) return new[] { _source };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									var execCount = (int)Math.Ceiling(1.0 * _source.Count / valuesLimit);
 | 
				
			||||||
 | 
									var ret = new List<T1>[execCount];
 | 
				
			||||||
 | 
									for (var a = 0; a < execCount; a++) {
 | 
				
			||||||
 | 
										var subSource = new List<T1>();
 | 
				
			||||||
 | 
										subSource = _source.GetRange(a * valuesLimit, Math.Min(valuesLimit, _source.Count - a * valuesLimit));
 | 
				
			||||||
 | 
										ret[a] = subSource;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									return ret;
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									var colSum = _table.Columns.Count - _ignore.Count;
 | 
				
			||||||
 | 
									var takeMax = parameterLimit / colSum;
 | 
				
			||||||
 | 
									var pamTotal = colSum * _source.Count;
 | 
				
			||||||
 | 
									if (pamTotal < parameterLimit) return new[] { _source };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									var execCount = (int)Math.Ceiling(1.0 * pamTotal / parameterLimit);
 | 
				
			||||||
 | 
									var ret = new List<T1>[execCount];
 | 
				
			||||||
 | 
									for (var a = 0; a < execCount; a++) {
 | 
				
			||||||
 | 
										var subSource = new List<T1>();
 | 
				
			||||||
 | 
										subSource = _source.GetRange(a * takeMax, Math.Min(takeMax, _source.Count - a * takeMax));
 | 
				
			||||||
 | 
										ret[a] = subSource;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									return ret;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							internal int SplitExecuteAffrows(int valuesLimit, int parameterLimit) {
 | 
				
			||||||
 | 
								var ss = SplitSource(valuesLimit, parameterLimit);
 | 
				
			||||||
 | 
								if (ss.Any() == false) return 0;
 | 
				
			||||||
 | 
								if (ss.Length == 1) return this.RawExecuteAffrows();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								var ret = 0;
 | 
				
			||||||
 | 
								if (_transaction != null) {
 | 
				
			||||||
 | 
									for (var a = 0; a < ss.Length; a++) {
 | 
				
			||||||
 | 
										_source = ss[a];
 | 
				
			||||||
 | 
										ret += this.RawExecuteAffrows();
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									using (var conn = _orm.Ado.MasterPool.Get()) {
 | 
				
			||||||
 | 
										_transaction = conn.Value.BeginTransaction();
 | 
				
			||||||
 | 
										try {
 | 
				
			||||||
 | 
											for (var a = 0; a < ss.Length; a++) {
 | 
				
			||||||
 | 
												_source = ss[a];
 | 
				
			||||||
 | 
												ret += this.RawExecuteAffrows();
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											_transaction.Commit();
 | 
				
			||||||
 | 
										} catch {
 | 
				
			||||||
 | 
											_transaction.Rollback();
 | 
				
			||||||
 | 
											throw;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										_transaction = null;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return ret;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							async internal Task<int> SplitExecuteAffrowsAsync(int valuesLimit, int parameterLimit) {
 | 
				
			||||||
 | 
								var ss = SplitSource(valuesLimit, parameterLimit);
 | 
				
			||||||
 | 
								if (ss.Any() == false) return 0;
 | 
				
			||||||
 | 
								if (ss.Length == 1) return await this.RawExecuteAffrowsAsync();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								var ret = 0;
 | 
				
			||||||
 | 
								if (_transaction != null) {
 | 
				
			||||||
 | 
									for (var a = 0; a < ss.Length; a++) {
 | 
				
			||||||
 | 
										_source = ss[a];
 | 
				
			||||||
 | 
										ret += await this.RawExecuteAffrowsAsync();
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									using (var conn = await _orm.Ado.MasterPool.GetAsync()) {
 | 
				
			||||||
 | 
										_transaction = conn.Value.BeginTransaction();
 | 
				
			||||||
 | 
										try {
 | 
				
			||||||
 | 
											for (var a = 0; a < ss.Length; a++) {
 | 
				
			||||||
 | 
												_source = ss[a];
 | 
				
			||||||
 | 
												ret += await this.RawExecuteAffrowsAsync();
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											_transaction.Commit();
 | 
				
			||||||
 | 
										} catch {
 | 
				
			||||||
 | 
											_transaction.Rollback();
 | 
				
			||||||
 | 
											throw;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										_transaction = null;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return ret;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							internal long SplitExecuteIdentity(int valuesLimit, int parameterLimit) {
 | 
				
			||||||
 | 
								var ss = SplitSource(valuesLimit, parameterLimit);
 | 
				
			||||||
 | 
								if (ss.Any() == false) return 0;
 | 
				
			||||||
 | 
								if (ss.Length == 1) return this.RawExecuteIdentity();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								long ret = 0;
 | 
				
			||||||
 | 
								if (_transaction != null) {
 | 
				
			||||||
 | 
									for (var a = 0; a < ss.Length; a++) {
 | 
				
			||||||
 | 
										_source = ss[a];
 | 
				
			||||||
 | 
										if (a < ss.Length - 1) this.RawExecuteAffrows();
 | 
				
			||||||
 | 
										else ret = this.RawExecuteIdentity();
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									using (var conn = _orm.Ado.MasterPool.Get()) {
 | 
				
			||||||
 | 
										_transaction = conn.Value.BeginTransaction();
 | 
				
			||||||
 | 
										try {
 | 
				
			||||||
 | 
											for (var a = 0; a < ss.Length; a++) {
 | 
				
			||||||
 | 
												_source = ss[a];
 | 
				
			||||||
 | 
												if (a < ss.Length - 1) this.RawExecuteAffrows();
 | 
				
			||||||
 | 
												else ret = this.RawExecuteIdentity();
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											_transaction.Commit();
 | 
				
			||||||
 | 
										} catch {
 | 
				
			||||||
 | 
											_transaction.Rollback();
 | 
				
			||||||
 | 
											throw;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										_transaction = null;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return ret;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							async internal Task<long> SplitExecuteIdentityAsync(int valuesLimit, int parameterLimit) {
 | 
				
			||||||
 | 
								var ss = SplitSource(valuesLimit, parameterLimit);
 | 
				
			||||||
 | 
								if (ss.Any() == false) return 0;
 | 
				
			||||||
 | 
								if (ss.Length == 1) return await this.RawExecuteIdentityAsync();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								long ret = 0;
 | 
				
			||||||
 | 
								if (_transaction != null) {
 | 
				
			||||||
 | 
									for (var a = 0; a < ss.Length; a++) {
 | 
				
			||||||
 | 
										_source = ss[a];
 | 
				
			||||||
 | 
										if (a < ss.Length - 1) await this.RawExecuteAffrowsAsync();
 | 
				
			||||||
 | 
										else ret = await this.RawExecuteIdentityAsync();
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									using (var conn = await _orm.Ado.MasterPool.GetAsync()) {
 | 
				
			||||||
 | 
										_transaction = conn.Value.BeginTransaction();
 | 
				
			||||||
 | 
										try {
 | 
				
			||||||
 | 
											for (var a = 0; a < ss.Length; a++) {
 | 
				
			||||||
 | 
												_source = ss[a];
 | 
				
			||||||
 | 
												if (a < ss.Length - 1) await this.RawExecuteAffrowsAsync();
 | 
				
			||||||
 | 
												else ret = await this.RawExecuteIdentityAsync();
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											_transaction.Commit();
 | 
				
			||||||
 | 
										} catch {
 | 
				
			||||||
 | 
											_transaction.Rollback();
 | 
				
			||||||
 | 
											throw;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										_transaction = null;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return ret;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							internal List<T1> SplitExecuteInserted(int valuesLimit, int parameterLimit) {
 | 
				
			||||||
 | 
								var ss = SplitSource(valuesLimit, parameterLimit);
 | 
				
			||||||
 | 
								if (ss.Any() == false) return new List<T1>();
 | 
				
			||||||
 | 
								if (ss.Length == 1) return this.RawExecuteInserted();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								var ret = new List<T1>();
 | 
				
			||||||
 | 
								if (_transaction != null) {
 | 
				
			||||||
 | 
									for (var a = 0; a < ss.Length; a++) {
 | 
				
			||||||
 | 
										_source = ss[a];
 | 
				
			||||||
 | 
										ret.AddRange(this.RawExecuteInserted());
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									using (var conn = _orm.Ado.MasterPool.Get()) {
 | 
				
			||||||
 | 
										_transaction = conn.Value.BeginTransaction();
 | 
				
			||||||
 | 
										try {
 | 
				
			||||||
 | 
											for (var a = 0; a < ss.Length; a++) {
 | 
				
			||||||
 | 
												_source = ss[a];
 | 
				
			||||||
 | 
												ret.AddRange(this.RawExecuteInserted());
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											_transaction.Commit();
 | 
				
			||||||
 | 
										} catch {
 | 
				
			||||||
 | 
											_transaction.Rollback();
 | 
				
			||||||
 | 
											throw;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										_transaction = null;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return ret;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							async internal Task<List<T1>> SplitExecuteInsertedAsync(int valuesLimit, int parameterLimit) {
 | 
				
			||||||
 | 
								var ss = SplitSource(valuesLimit, parameterLimit);
 | 
				
			||||||
 | 
								if (ss.Any() == false) return new List<T1>();
 | 
				
			||||||
 | 
								if (ss.Length == 1) return await this.RawExecuteInsertedAsync();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								var ret = new List<T1>();
 | 
				
			||||||
 | 
								if (_transaction != null) {
 | 
				
			||||||
 | 
									for (var a = 0; a < ss.Length; a++) {
 | 
				
			||||||
 | 
										_source = ss[a];
 | 
				
			||||||
 | 
										ret.AddRange(await this.RawExecuteInsertedAsync());
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									using (var conn = await _orm.Ado.MasterPool.GetAsync()) {
 | 
				
			||||||
 | 
										_transaction = conn.Value.BeginTransaction();
 | 
				
			||||||
 | 
										try {
 | 
				
			||||||
 | 
											for (var a = 0; a < ss.Length; a++) {
 | 
				
			||||||
 | 
												_source = ss[a];
 | 
				
			||||||
 | 
												ret.AddRange(await this.RawExecuteInsertedAsync());
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											_transaction.Commit();
 | 
				
			||||||
 | 
										} catch {
 | 
				
			||||||
 | 
											_transaction.Rollback();
 | 
				
			||||||
 | 
											throw;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										_transaction = null;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return ret;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							internal int RawExecuteAffrows() => _orm.Ado.ExecuteNonQuery(_transaction, CommandType.Text, ToSql(), _params);
 | 
				
			||||||
 | 
							internal Task<int> RawExecuteAffrowsAsync() => _orm.Ado.ExecuteNonQueryAsync(_transaction, CommandType.Text, ToSql(), _params);
 | 
				
			||||||
 | 
							internal abstract long RawExecuteIdentity();
 | 
				
			||||||
 | 
							internal abstract Task<long> RawExecuteIdentityAsync();
 | 
				
			||||||
 | 
							internal abstract List<T1> RawExecuteInserted();
 | 
				
			||||||
 | 
							internal abstract Task<List<T1>> RawExecuteInsertedAsync();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public virtual int ExecuteAffrows() => RawExecuteAffrows();
 | 
				
			||||||
 | 
							public virtual Task<int> ExecuteAffrowsAsync() => RawExecuteAffrowsAsync();
 | 
				
			||||||
		public abstract long ExecuteIdentity();
 | 
							public abstract long ExecuteIdentity();
 | 
				
			||||||
		public abstract Task<long> ExecuteIdentityAsync();
 | 
							public abstract Task<long> ExecuteIdentityAsync();
 | 
				
			||||||
		public abstract List<T1> ExecuteInserted();
 | 
							public abstract List<T1> ExecuteInserted();
 | 
				
			||||||
@@ -81,9 +308,8 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
					++colidx;
 | 
										++colidx;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			sb.Append(") VALUES");
 | 
								sb.Append(") VALUES");
 | 
				
			||||||
			//_params = new DbParameter[colidx * _source.Count];
 | 
								_params = _noneParameter ? new DbParameter[0] : new DbParameter[colidx * _source.Count];
 | 
				
			||||||
			_params = new DbParameter[0];
 | 
								var specialParams = new List<DbParameter>();
 | 
				
			||||||
			//_params = new DbParameter[colidx * 5]; //批量添加第5行起,不使用参数化
 | 
					 | 
				
			||||||
			var didx = 0;
 | 
								var didx = 0;
 | 
				
			||||||
			foreach (var d in _source) {
 | 
								foreach (var d in _source) {
 | 
				
			||||||
				if (didx > 0) sb.Append(", ");
 | 
									if (didx > 0) sb.Append(", ");
 | 
				
			||||||
@@ -98,17 +324,19 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
							if (col.Attribute.IsPrimary && (col.CsType == typeof(Guid) || col.CsType == typeof(Guid?))
 | 
												if (col.Attribute.IsPrimary && (col.CsType == typeof(Guid) || col.CsType == typeof(Guid?))
 | 
				
			||||||
								&& (val == null || (Guid)val == Guid.Empty)) tryp.SetValue(d, val = FreeUtil.NewMongodbId());
 | 
													&& (val == null || (Guid)val == Guid.Empty)) tryp.SetValue(d, val = FreeUtil.NewMongodbId());
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
						//if (didx >= 5)
 | 
											if (_noneParameter)
 | 
				
			||||||
							sb.Append(_commonUtils.GetNoneParamaterSqlValue(col.CsType, val));
 | 
												sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.CsType, val));
 | 
				
			||||||
						//else {
 | 
											else {
 | 
				
			||||||
						//	sb.Append(_commonUtils.QuoteWriteParamter(col.CsType, $"{_commonUtils.QuoteParamterName(col.CsName)}{didx}"));
 | 
												sb.Append(_commonUtils.QuoteWriteParamter(col.CsType, _commonUtils.QuoteParamterName($"{col.CsName}{didx}")));
 | 
				
			||||||
						//	_params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}{didx}", col.CsType, val);
 | 
												_params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}{didx}", col.CsType, val);
 | 
				
			||||||
						//}
 | 
											}
 | 
				
			||||||
						++colidx2;
 | 
											++colidx2;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				sb.Append(")");
 | 
									sb.Append(")");
 | 
				
			||||||
				++didx;
 | 
									++didx;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								if (_noneParameter && specialParams.Any())
 | 
				
			||||||
 | 
									_params = specialParams.ToArray();
 | 
				
			||||||
			return sb.ToString();
 | 
								return sb.ToString();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -279,7 +279,7 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
			public Func<DbDataReader, T1> Read { get; set; }
 | 
								public Func<DbDataReader, T1> Read { get; set; }
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		protected GetAllFieldExpressionTreeInfo GetAllFieldExpressionTree() {
 | 
							protected GetAllFieldExpressionTreeInfo GetAllFieldExpressionTree() {
 | 
				
			||||||
			return _dicGetAllFieldExpressionTree.GetOrAdd(string.Join("+", _tables.Select(a => $"{_commonUtils.DbName}-{a.Table.DbName}-{a.Alias}-{a.Type}")), s => {
 | 
								return _dicGetAllFieldExpressionTree.GetOrAdd(string.Join("+", _tables.Select(a => $"{_orm.Ado.DataType}-{a.Table.DbName}-{a.Alias}-{a.Type}")), s => {
 | 
				
			||||||
				var tb1 = _tables.First().Table;
 | 
									var tb1 = _tables.First().Table;
 | 
				
			||||||
				var type = tb1.TypeLazy ?? tb1.Type;
 | 
									var type = tb1.TypeLazy ?? tb1.Type;
 | 
				
			||||||
				var props = tb1.Properties;
 | 
									var props = tb1.Properties;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,6 +22,7 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
		protected StringBuilder _set = new StringBuilder();
 | 
							protected StringBuilder _set = new StringBuilder();
 | 
				
			||||||
		protected List<DbParameter> _params = new List<DbParameter>();
 | 
							protected List<DbParameter> _params = new List<DbParameter>();
 | 
				
			||||||
		protected List<DbParameter> _paramsSource = new List<DbParameter>();
 | 
							protected List<DbParameter> _paramsSource = new List<DbParameter>();
 | 
				
			||||||
 | 
							protected bool _noneParameter;
 | 
				
			||||||
		protected DbTransaction _transaction;
 | 
							protected DbTransaction _transaction;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public UpdateProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) {
 | 
							public UpdateProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) {
 | 
				
			||||||
@@ -29,6 +30,7 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
			_commonUtils = commonUtils;
 | 
								_commonUtils = commonUtils;
 | 
				
			||||||
			_commonExpression = commonExpression;
 | 
								_commonExpression = commonExpression;
 | 
				
			||||||
			_table = _commonUtils.GetTableByEntity(typeof(T1));
 | 
								_table = _commonUtils.GetTableByEntity(typeof(T1));
 | 
				
			||||||
 | 
								_noneParameter = _orm.CodeFirst.IsNoneCommandParameter;
 | 
				
			||||||
			this.Where(_commonUtils.WhereObject(_table, "", dywhere));
 | 
								this.Where(_commonUtils.WhereObject(_table, "", dywhere));
 | 
				
			||||||
			if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure<T1>();
 | 
								if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure<T1>();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -37,6 +39,10 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
			_transaction = transaction;
 | 
								_transaction = transaction;
 | 
				
			||||||
			return this;
 | 
								return this;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							public IUpdate<T1> NoneParameter() {
 | 
				
			||||||
 | 
								_noneParameter = false;
 | 
				
			||||||
 | 
								return this;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public int ExecuteAffrows() {
 | 
							public int ExecuteAffrows() {
 | 
				
			||||||
			var sql = this.ToSql();
 | 
								var sql = this.ToSql();
 | 
				
			||||||
@@ -70,8 +76,13 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
			_commonExpression.ExpressionSelectColumn_MemberAccess(null, cols, SelectTableInfoType.From, column?.Body, true, null);
 | 
								_commonExpression.ExpressionSelectColumn_MemberAccess(null, cols, SelectTableInfoType.From, column?.Body, true, null);
 | 
				
			||||||
			if (cols.Count != 1) return this;
 | 
								if (cols.Count != 1) return this;
 | 
				
			||||||
			var col = cols.First();
 | 
								var col = cols.First();
 | 
				
			||||||
			_set.Append(", ").Append(_commonUtils.QuoteSqlName(col.Column.Attribute.Name)).Append(" = ").Append(_commonUtils.QuoteWriteParamter(col.Column.CsType, $"{_commonUtils.QuoteParamterName("p_")}{_params.Count}"));
 | 
								_set.Append(", ").Append(_commonUtils.QuoteSqlName(col.Column.Attribute.Name)).Append(" = ");
 | 
				
			||||||
			_commonUtils.AppendParamter(_params, null, col.Column.CsType, value);
 | 
								if (_noneParameter) {
 | 
				
			||||||
 | 
									_set.Append(_commonUtils.GetNoneParamaterSqlValue(_params, col.Column.CsType, value));
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									_set.Append(_commonUtils.QuoteWriteParamter(col.Column.CsType, $"{_commonUtils.QuoteParamterName("p_")}{_params.Count}"));
 | 
				
			||||||
 | 
									_commonUtils.AppendParamter(_params, null, col.Column.CsType, value);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			//foreach (var t in _source) Utils.FillPropertyValue(t, tryf.CsName, value);
 | 
								//foreach (var t in _source) Utils.FillPropertyValue(t, tryf.CsName, value);
 | 
				
			||||||
			return this;
 | 
								return this;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -131,8 +142,14 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
				foreach (var col in _table.Columns.Values) {
 | 
									foreach (var col in _table.Columns.Values) {
 | 
				
			||||||
					if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.CsName) == false) {
 | 
										if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.CsName) == false) {
 | 
				
			||||||
						if (colidx > 0) sb.Append(", ");
 | 
											if (colidx > 0) sb.Append(", ");
 | 
				
			||||||
						sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = ").Append(_commonUtils.QuoteWriteParamter(col.CsType, _commonUtils.QuoteParamterName($"p_{_paramsSource.Count}")));
 | 
											sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = ");
 | 
				
			||||||
						_commonUtils.AppendParamter(_paramsSource, null, col.CsType, _table.Properties.TryGetValue(col.CsName, out var tryp) ? tryp.GetValue(_source.First()) : null);
 | 
											var value = _table.Properties.TryGetValue(col.CsName, out var tryp) ? tryp.GetValue(_source.First()) : null;
 | 
				
			||||||
 | 
											if (_noneParameter) {
 | 
				
			||||||
 | 
												sb.Append(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.CsType, value));
 | 
				
			||||||
 | 
											} else {
 | 
				
			||||||
 | 
												sb.Append(_commonUtils.QuoteWriteParamter(col.CsType, _commonUtils.QuoteParamterName($"p_{_paramsSource.Count}")));
 | 
				
			||||||
 | 
												_commonUtils.AppendParamter(_paramsSource, null, col.CsType, value);
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
						++colidx;
 | 
											++colidx;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@@ -171,8 +188,14 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
							//	++pkidx;
 | 
												//	++pkidx;
 | 
				
			||||||
							//}
 | 
												//}
 | 
				
			||||||
							//if (_table.Primarys.Length > 1) sb.Append(")");
 | 
												//if (_table.Primarys.Length > 1) sb.Append(")");
 | 
				
			||||||
							sb.Append(" THEN ").Append(_commonUtils.QuoteWriteParamter(col.CsType, _commonUtils.QuoteParamterName($"p_{_paramsSource.Count}")));
 | 
												sb.Append(" THEN ");
 | 
				
			||||||
							_commonUtils.AppendParamter(_paramsSource, null, col.CsType, _table.Properties.TryGetValue(col.CsName, out var tryp) ? tryp.GetValue(d) : DBNull.Value);
 | 
												var value = _table.Properties.TryGetValue(col.CsName, out var tryp) ? tryp.GetValue(d) : DBNull.Value;
 | 
				
			||||||
 | 
												if (_noneParameter) {
 | 
				
			||||||
 | 
													sb.Append(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.CsType, value));
 | 
				
			||||||
 | 
												} else {
 | 
				
			||||||
 | 
													sb.Append(_commonUtils.QuoteWriteParamter(col.CsType, _commonUtils.QuoteParamterName($"p_{_paramsSource.Count}")));
 | 
				
			||||||
 | 
													_commonUtils.AppendParamter(_paramsSource, null, col.CsType, value);
 | 
				
			||||||
 | 
												}
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
						sb.Append(" END");
 | 
											sb.Append(" END");
 | 
				
			||||||
						++colidx;
 | 
											++colidx;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,9 +13,9 @@ using System.Text;
 | 
				
			|||||||
namespace FreeSql.Internal {
 | 
					namespace FreeSql.Internal {
 | 
				
			||||||
	internal abstract class CommonUtils {
 | 
						internal abstract class CommonUtils {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		internal abstract string GetNoneParamaterSqlValue(Type type, object value);
 | 
							internal abstract string GetNoneParamaterSqlValue(List<DbParameter> specialParams, Type type, object value);
 | 
				
			||||||
		internal abstract DbParameter[] GetDbParamtersByObject(string sql, object obj);
 | 
					 | 
				
			||||||
		internal abstract DbParameter AppendParamter(List<DbParameter> _params, string parameterName, Type type, object value);
 | 
							internal abstract DbParameter AppendParamter(List<DbParameter> _params, string parameterName, Type type, object value);
 | 
				
			||||||
 | 
							internal abstract DbParameter[] GetDbParamtersByObject(string sql, object obj);
 | 
				
			||||||
		internal abstract string FormatSql(string sql, params object[] args);
 | 
							internal abstract string FormatSql(string sql, params object[] args);
 | 
				
			||||||
		internal abstract string QuoteSqlName(string name);
 | 
							internal abstract string QuoteSqlName(string name);
 | 
				
			||||||
		internal abstract string QuoteParamterName(string name);
 | 
							internal abstract string QuoteParamterName(string name);
 | 
				
			||||||
@@ -24,7 +24,6 @@ namespace FreeSql.Internal {
 | 
				
			|||||||
		internal abstract string Mod(string left, string right, Type leftType, Type rightType);
 | 
							internal abstract string Mod(string left, string right, Type leftType, Type rightType);
 | 
				
			||||||
		internal abstract string QuoteWriteParamter(Type type, string paramterName);
 | 
							internal abstract string QuoteWriteParamter(Type type, string paramterName);
 | 
				
			||||||
		internal abstract string QuoteReadColumn(Type type, string columnName);
 | 
							internal abstract string QuoteReadColumn(Type type, string columnName);
 | 
				
			||||||
		internal abstract string DbName { get; }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		internal IFreeSql _orm { get; set; }
 | 
							internal IFreeSql _orm { get; set; }
 | 
				
			||||||
		internal ICodeFirst CodeFirst => _orm.CodeFirst;
 | 
							internal ICodeFirst CodeFirst => _orm.CodeFirst;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,37 +1,28 @@
 | 
				
			|||||||
using FreeSql.DataAnnotations;
 | 
					using FreeSql.DataAnnotations;
 | 
				
			||||||
using FreeSql.Internal.Model;
 | 
					using FreeSql.Internal.Model;
 | 
				
			||||||
using Newtonsoft.Json.Linq;
 | 
					using Newtonsoft.Json.Linq;
 | 
				
			||||||
using Npgsql.LegacyPostgis;
 | 
					 | 
				
			||||||
using NpgsqlTypes;
 | 
					 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections;
 | 
					 | 
				
			||||||
using System.Collections.Concurrent;
 | 
					using System.Collections.Concurrent;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Data;
 | 
					 | 
				
			||||||
using System.Data.Common;
 | 
					using System.Data.Common;
 | 
				
			||||||
using System.Diagnostics;
 | 
					 | 
				
			||||||
using System.IO;
 | 
					 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
using System.Linq.Expressions;
 | 
					using System.Linq.Expressions;
 | 
				
			||||||
using System.Net;
 | 
					 | 
				
			||||||
using System.Net.NetworkInformation;
 | 
					 | 
				
			||||||
using System.Reflection;
 | 
					using System.Reflection;
 | 
				
			||||||
using System.Text;
 | 
					using System.Text;
 | 
				
			||||||
using System.Text.RegularExpressions;
 | 
					using System.Text.RegularExpressions;
 | 
				
			||||||
using System.Threading;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace FreeSql.Internal {
 | 
					namespace FreeSql.Internal {
 | 
				
			||||||
	class Utils {
 | 
						class Utils {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		static ConcurrentDictionary<string, ConcurrentDictionary<Type, TableInfo>> _cacheGetTableByEntity = new ConcurrentDictionary<string, ConcurrentDictionary<Type, TableInfo>>();
 | 
							static ConcurrentDictionary<DataType, ConcurrentDictionary<Type, TableInfo>> _cacheGetTableByEntity = new ConcurrentDictionary<DataType, ConcurrentDictionary<Type, TableInfo>>();
 | 
				
			||||||
		internal static void RemoveTableByEntity(Type entity, CommonUtils common) {
 | 
							internal static void RemoveTableByEntity(Type entity, CommonUtils common) {
 | 
				
			||||||
			if (entity.FullName.StartsWith("<>f__AnonymousType")) return;
 | 
								if (entity.FullName.StartsWith("<>f__AnonymousType")) return;
 | 
				
			||||||
			var tbc = _cacheGetTableByEntity.GetOrAdd(common.DbName, k1 => new ConcurrentDictionary<Type, TableInfo>()); //区分数据库类型缓存
 | 
								var tbc = _cacheGetTableByEntity.GetOrAdd(common._orm.Ado.DataType, k1 => new ConcurrentDictionary<Type, TableInfo>()); //区分数据库类型缓存
 | 
				
			||||||
			tbc.TryRemove(entity, out var trytb);
 | 
								tbc.TryRemove(entity, out var trytb);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		internal static TableInfo GetTableByEntity(Type entity, CommonUtils common) {
 | 
							internal static TableInfo GetTableByEntity(Type entity, CommonUtils common) {
 | 
				
			||||||
			if (entity.FullName.StartsWith("<>f__AnonymousType")) return null;
 | 
								if (entity.FullName.StartsWith("<>f__AnonymousType")) return null;
 | 
				
			||||||
			var tbc = _cacheGetTableByEntity.GetOrAdd(common.DbName, k1 => new ConcurrentDictionary<Type, TableInfo>()); //区分数据库类型缓存
 | 
								var tbc = _cacheGetTableByEntity.GetOrAdd(common._orm.Ado.DataType, k1 => new ConcurrentDictionary<Type, TableInfo>()); //区分数据库类型缓存
 | 
				
			||||||
			if (tbc.TryGetValue(entity, out var trytb)) return trytb;
 | 
								if (tbc.TryGetValue(entity, out var trytb)) return trytb;
 | 
				
			||||||
			if (common.CodeFirst.GetDbInfo(entity) != null) return null;
 | 
								if (common.CodeFirst.GetDbInfo(entity) != null) return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -528,39 +519,39 @@ namespace FreeSql.Internal {
 | 
				
			|||||||
			[typeof(byte[])] = true,
 | 
								[typeof(byte[])] = true,
 | 
				
			||||||
			[typeof(string)] = true,
 | 
								[typeof(string)] = true,
 | 
				
			||||||
			[typeof(Guid)] = true,
 | 
								[typeof(Guid)] = true,
 | 
				
			||||||
			[typeof(MygisPoint)] = true,
 | 
								//[typeof(MygisPoint)] = true,
 | 
				
			||||||
			[typeof(MygisLineString)] = true,
 | 
								//[typeof(MygisLineString)] = true,
 | 
				
			||||||
			[typeof(MygisPolygon)] = true,
 | 
								//[typeof(MygisPolygon)] = true,
 | 
				
			||||||
			[typeof(MygisMultiPoint)] = true,
 | 
								//[typeof(MygisMultiPoint)] = true,
 | 
				
			||||||
			[typeof(MygisMultiLineString)] = true,
 | 
								//[typeof(MygisMultiLineString)] = true,
 | 
				
			||||||
			[typeof(MygisMultiPolygon)] = true,
 | 
								//[typeof(MygisMultiPolygon)] = true,
 | 
				
			||||||
			[typeof(BitArray)] = true,
 | 
								//[typeof(BitArray)] = true,
 | 
				
			||||||
			[typeof(NpgsqlPoint)] = true,
 | 
								//[typeof(NpgsqlPoint)] = true,
 | 
				
			||||||
			[typeof(NpgsqlLine)] = true,
 | 
								//[typeof(NpgsqlLine)] = true,
 | 
				
			||||||
			[typeof(NpgsqlLSeg)] = true,
 | 
								//[typeof(NpgsqlLSeg)] = true,
 | 
				
			||||||
			[typeof(NpgsqlBox)] = true,
 | 
								//[typeof(NpgsqlBox)] = true,
 | 
				
			||||||
			[typeof(NpgsqlPath)] = true,
 | 
								//[typeof(NpgsqlPath)] = true,
 | 
				
			||||||
			[typeof(NpgsqlPolygon)] = true,
 | 
								//[typeof(NpgsqlPolygon)] = true,
 | 
				
			||||||
			[typeof(NpgsqlCircle)] = true,
 | 
								//[typeof(NpgsqlCircle)] = true,
 | 
				
			||||||
			[typeof((IPAddress Address, int Subnet))] = true,
 | 
								//[typeof((IPAddress Address, int Subnet))] = true,
 | 
				
			||||||
			[typeof(IPAddress)] = true,
 | 
								//[typeof(IPAddress)] = true,
 | 
				
			||||||
			[typeof(PhysicalAddress)] = true,
 | 
								//[typeof(PhysicalAddress)] = true,
 | 
				
			||||||
			[typeof(NpgsqlRange<int>)] = true,
 | 
								//[typeof(NpgsqlRange<int>)] = true,
 | 
				
			||||||
			[typeof(NpgsqlRange<long>)] = true,
 | 
								//[typeof(NpgsqlRange<long>)] = true,
 | 
				
			||||||
			[typeof(NpgsqlRange<decimal>)] = true,
 | 
								//[typeof(NpgsqlRange<decimal>)] = true,
 | 
				
			||||||
			[typeof(NpgsqlRange<DateTime>)] = true,
 | 
								//[typeof(NpgsqlRange<DateTime>)] = true,
 | 
				
			||||||
			[typeof(PostgisPoint)] = true,
 | 
								//[typeof(PostgisPoint)] = true,
 | 
				
			||||||
			[typeof(PostgisLineString)] = true,
 | 
								//[typeof(PostgisLineString)] = true,
 | 
				
			||||||
			[typeof(PostgisPolygon)] = true,
 | 
								//[typeof(PostgisPolygon)] = true,
 | 
				
			||||||
			[typeof(PostgisMultiPoint)] = true,
 | 
								//[typeof(PostgisMultiPoint)] = true,
 | 
				
			||||||
			[typeof(PostgisMultiLineString)] = true,
 | 
								//[typeof(PostgisMultiLineString)] = true,
 | 
				
			||||||
			[typeof(PostgisMultiPolygon)] = true,
 | 
								//[typeof(PostgisMultiPolygon)] = true,
 | 
				
			||||||
			[typeof(PostgisGeometry)] = true,
 | 
								//[typeof(PostgisGeometry)] = true,
 | 
				
			||||||
			[typeof(PostgisGeometryCollection)] = true,
 | 
								//[typeof(PostgisGeometryCollection)] = true,
 | 
				
			||||||
			[typeof(Dictionary<string, string>)] = true,
 | 
								//[typeof(Dictionary<string, string>)] = true,
 | 
				
			||||||
			[typeof(JToken)] = true,
 | 
								//[typeof(JToken)] = true,
 | 
				
			||||||
			[typeof(JObject)] = true,
 | 
								//[typeof(JObject)] = true,
 | 
				
			||||||
			[typeof(JArray)] = true,
 | 
								//[typeof(JArray)] = true,
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
		internal static ConcurrentDictionary<Type, Func<Type, int[], DbDataReader, int, RowInfo>> _dicExecuteArrayRowReadClassOrTuple = new ConcurrentDictionary<Type, Func<Type, int[], DbDataReader, int, RowInfo>>();
 | 
							internal static ConcurrentDictionary<Type, Func<Type, int[], DbDataReader, int, RowInfo>> _dicExecuteArrayRowReadClassOrTuple = new ConcurrentDictionary<Type, Func<Type, int[], DbDataReader, int, RowInfo>>();
 | 
				
			||||||
		internal class RowInfo {
 | 
							internal class RowInfo {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,20 +11,27 @@ namespace FreeSql.MySql.Curd {
 | 
				
			|||||||
			: base(orm, commonUtils, commonExpression) {
 | 
								: base(orm, commonUtils, commonExpression) {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public override long ExecuteIdentity() {
 | 
							public override int ExecuteAffrows() => base.SplitExecuteAffrows(5000, 3000);
 | 
				
			||||||
 | 
							public override Task<int> ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(5000, 3000);
 | 
				
			||||||
 | 
							public override long ExecuteIdentity() => base.SplitExecuteIdentity(5000, 3000);
 | 
				
			||||||
 | 
							public override Task<long> ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(5000, 3000);
 | 
				
			||||||
 | 
							public override List<T1> ExecuteInserted() => base.SplitExecuteInserted(5000, 3000);
 | 
				
			||||||
 | 
							public override Task<List<T1>> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(5000, 3000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							internal override long RawExecuteIdentity() {
 | 
				
			||||||
			var sql = this.ToSql();
 | 
								var sql = this.ToSql();
 | 
				
			||||||
			if (string.IsNullOrEmpty(sql)) return 0;
 | 
								if (string.IsNullOrEmpty(sql)) return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_transaction, CommandType.Text, string.Concat(sql, "; SELECT LAST_INSERT_ID();"), _params)), out var trylng) ? trylng : 0;
 | 
								return long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_transaction, CommandType.Text, string.Concat(sql, "; SELECT LAST_INSERT_ID();"), _params)), out var trylng) ? trylng : 0;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		async public override Task<long> ExecuteIdentityAsync() {
 | 
							async internal override Task<long> RawExecuteIdentityAsync() {
 | 
				
			||||||
			var sql = this.ToSql();
 | 
								var sql = this.ToSql();
 | 
				
			||||||
			if (string.IsNullOrEmpty(sql)) return 0;
 | 
								if (string.IsNullOrEmpty(sql)) return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_transaction, CommandType.Text, string.Concat(sql, "; SELECT LAST_INSERT_ID();"), _params)), out var trylng) ? trylng : 0;
 | 
								return long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_transaction, CommandType.Text, string.Concat(sql, "; SELECT LAST_INSERT_ID();"), _params)), out var trylng) ? trylng : 0;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							internal override List<T1> RawExecuteInserted() {
 | 
				
			||||||
		public override List<T1> ExecuteInserted() {
 | 
					 | 
				
			||||||
			var sql = this.ToSql();
 | 
								var sql = this.ToSql();
 | 
				
			||||||
			if (string.IsNullOrEmpty(sql)) return new List<T1>();
 | 
								if (string.IsNullOrEmpty(sql)) return new List<T1>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -39,7 +46,7 @@ namespace FreeSql.MySql.Curd {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
			return _orm.Ado.Query<T1>(_transaction, CommandType.Text, sb.ToString(), _params);
 | 
								return _orm.Ado.Query<T1>(_transaction, CommandType.Text, sb.ToString(), _params);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		async public override Task<List<T1>> ExecuteInsertedAsync() {
 | 
							async internal override Task<List<T1>> RawExecuteInsertedAsync() {
 | 
				
			||||||
			var sql = this.ToSql();
 | 
								var sql = this.ToSql();
 | 
				
			||||||
			if (string.IsNullOrEmpty(sql)) return new List<T1>();
 | 
								if (string.IsNullOrEmpty(sql)) return new List<T1>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,10 +23,11 @@ namespace FreeSql.MySql {
 | 
				
			|||||||
			_commonExpression = commonExpression;
 | 
								_commonExpression = commonExpression;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public bool IsAutoSyncStructure { get; set; } = true;
 | 
							public bool IsAutoSyncStructure { get; set; } = false;
 | 
				
			||||||
		public bool IsSyncStructureToLower { get; set; } = false;
 | 
							public bool IsSyncStructureToLower { get; set; } = false;
 | 
				
			||||||
		public bool IsSyncStructureToUpper { get; set; } = false;
 | 
							public bool IsSyncStructureToUpper { get; set; } = false;
 | 
				
			||||||
		public bool IsConfigEntityFromDbFirst { get; set; } = false;
 | 
							public bool IsConfigEntityFromDbFirst { get; set; } = false;
 | 
				
			||||||
 | 
							public bool IsNoneCommandParameter { get; set; } = false;
 | 
				
			||||||
		public bool IsLazyLoading { get; set; } = false;
 | 
							public bool IsLazyLoading { get; set; } = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		static object _dicCsToDbLock = new object();
 | 
							static object _dicCsToDbLock = new object();
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										11
									
								
								FreeSql/MySql/MySqlExtensions.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								FreeSql/MySql/MySqlExtensions.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					public static class FreeSqlMySqlExtensions {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// <summary>
 | 
				
			||||||
 | 
						/// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换
 | 
				
			||||||
 | 
						/// </summary>
 | 
				
			||||||
 | 
						/// <param name="that"></param>
 | 
				
			||||||
 | 
						/// <param name="args"></param>
 | 
				
			||||||
 | 
						/// <returns></returns>
 | 
				
			||||||
 | 
						public static string FormatMySql(this string that, params object[] args) => _mysqlAdo.Addslashes(that, args);
 | 
				
			||||||
 | 
						static FreeSql.MySql.MySqlAdo _mysqlAdo = new FreeSql.MySql.MySqlAdo();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -12,6 +12,15 @@ namespace FreeSql.MySql {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	class MySqlProvider : IFreeSql {
 | 
						class MySqlProvider : IFreeSql {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							static MySqlProvider() {
 | 
				
			||||||
 | 
								Utils.dicExecuteArrayRowReadClassOrTuple.Add(typeof(MygisPoint), true);
 | 
				
			||||||
 | 
								Utils.dicExecuteArrayRowReadClassOrTuple.Add(typeof(MygisLineString), true);
 | 
				
			||||||
 | 
								Utils.dicExecuteArrayRowReadClassOrTuple.Add(typeof(MygisPolygon), true);
 | 
				
			||||||
 | 
								Utils.dicExecuteArrayRowReadClassOrTuple.Add(typeof(MygisMultiPoint), true);
 | 
				
			||||||
 | 
								Utils.dicExecuteArrayRowReadClassOrTuple.Add(typeof(MygisMultiLineString), true);
 | 
				
			||||||
 | 
								Utils.dicExecuteArrayRowReadClassOrTuple.Add(typeof(MygisMultiPolygon), true);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public ISelect<T1> Select<T1>() where T1 : class => new MySqlSelect<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, null);
 | 
							public ISelect<T1> Select<T1>() where T1 : class => new MySqlSelect<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, null);
 | 
				
			||||||
		public ISelect<T1> Select<T1>(object dywhere) where T1 : class => new MySqlSelect<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere);
 | 
							public ISelect<T1> Select<T1>(object dywhere) where T1 : class => new MySqlSelect<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere);
 | 
				
			||||||
		public IInsert<T1> Insert<T1>() where T1 : class => new MySqlInsert<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression);
 | 
							public IInsert<T1> Insert<T1>() where T1 : class => new MySqlInsert<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,8 +14,7 @@ namespace FreeSql.MySql {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		internal override DbParameter AppendParamter(List<DbParameter> _params, string parameterName, Type type, object value) {
 | 
							internal override DbParameter AppendParamter(List<DbParameter> _params, string parameterName, Type type, object value) {
 | 
				
			||||||
			if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}";
 | 
								if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}";
 | 
				
			||||||
			else if (_orm.CodeFirst.IsSyncStructureToLower) parameterName = parameterName.ToLower();
 | 
								var ret = new MySqlParameter { ParameterName = QuoteParamterName(parameterName), Value = value };
 | 
				
			||||||
			var ret = new MySqlParameter { ParameterName = $"?{parameterName}", Value = value };
 | 
					 | 
				
			||||||
			var tp = _orm.CodeFirst.GetDbInfo(type)?.type;
 | 
								var tp = _orm.CodeFirst.GetDbInfo(type)?.type;
 | 
				
			||||||
			if (tp != null) {
 | 
								if (tp != null) {
 | 
				
			||||||
				if ((MySqlDbType)tp.Value == MySqlDbType.Geometry) {
 | 
									if ((MySqlDbType)tp.Value == MySqlDbType.Geometry) {
 | 
				
			||||||
@@ -72,7 +71,7 @@ namespace FreeSql.MySql {
 | 
				
			|||||||
			return columnName;
 | 
								return columnName;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		internal override string GetNoneParamaterSqlValue(Type type, object value) {
 | 
							internal override string GetNoneParamaterSqlValue(List<DbParameter> specialParams, Type type, object value) {
 | 
				
			||||||
			if (value == null) return "NULL";
 | 
								if (value == null) return "NULL";
 | 
				
			||||||
			if (type == typeof(byte[])) {
 | 
								if (type == typeof(byte[])) {
 | 
				
			||||||
				var bytes = value as byte[];
 | 
									var bytes = value as byte[];
 | 
				
			||||||
@@ -88,7 +87,5 @@ namespace FreeSql.MySql {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
			return FormatSql("{0}", value, 1);
 | 
								return FormatSql("{0}", value, 1);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					 | 
				
			||||||
		internal override string DbName => "MySql";
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,6 +16,14 @@ namespace FreeSql.Oracle.Curd {
 | 
				
			|||||||
			: base(orm, commonUtils, commonExpression) {
 | 
								: base(orm, commonUtils, commonExpression) {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 999);
 | 
				
			||||||
 | 
							public override Task<int> ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 999);
 | 
				
			||||||
 | 
							public override long ExecuteIdentity() => base.SplitExecuteIdentity(500, 999);
 | 
				
			||||||
 | 
							public override Task<long> ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(500, 999);
 | 
				
			||||||
 | 
							public override List<T1> ExecuteInserted() => base.SplitExecuteInserted(500, 999);
 | 
				
			||||||
 | 
							public override Task<List<T1>> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(500, 999);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public override string ToSql() {
 | 
							public override string ToSql() {
 | 
				
			||||||
			if (_source == null || _source.Any() == false) return null;
 | 
								if (_source == null || _source.Any() == false) return null;
 | 
				
			||||||
			var sb = new StringBuilder();
 | 
								var sb = new StringBuilder();
 | 
				
			||||||
@@ -40,9 +48,8 @@ namespace FreeSql.Oracle.Curd {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
			sbtb.Append(") ");
 | 
								sbtb.Append(") ");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			//_params = new DbParameter[colidx * _source.Count];
 | 
								_params = _noneParameter ? new DbParameter[0] : new DbParameter[colidx * _source.Count];
 | 
				
			||||||
			_params = new DbParameter[0];
 | 
								var specialParams = new List<DbParameter>();
 | 
				
			||||||
			//_params = new DbParameter[colidx * 5]; //批量添加第5行起,不使用参数化
 | 
					 | 
				
			||||||
			var didx = 0;
 | 
								var didx = 0;
 | 
				
			||||||
			foreach (var d in _source) {
 | 
								foreach (var d in _source) {
 | 
				
			||||||
				if (_source.Count > 1) sb.Append("\r\n");
 | 
									if (_source.Count > 1) sb.Append("\r\n");
 | 
				
			||||||
@@ -59,24 +66,24 @@ namespace FreeSql.Oracle.Curd {
 | 
				
			|||||||
							if (col.Attribute.IsPrimary && (col.CsType == typeof(Guid) || col.CsType == typeof(Guid?))
 | 
												if (col.Attribute.IsPrimary && (col.CsType == typeof(Guid) || col.CsType == typeof(Guid?))
 | 
				
			||||||
								&& (val == null || (Guid)val == Guid.Empty)) tryp.SetValue(d, val = FreeUtil.NewMongodbId());
 | 
													&& (val == null || (Guid)val == Guid.Empty)) tryp.SetValue(d, val = FreeUtil.NewMongodbId());
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
						//if (didx >= 5)
 | 
											if (_noneParameter)
 | 
				
			||||||
							sb.Append(_commonUtils.GetNoneParamaterSqlValue(col.CsType, val));
 | 
												sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.CsType, val));
 | 
				
			||||||
						//else {
 | 
											else {
 | 
				
			||||||
						//	sb.Append(_commonUtils.QuoteWriteParamter(col.CsType, $"{_commonUtils.QuoteParamterName(col.CsName)}{didx}"));
 | 
												sb.Append(_commonUtils.QuoteWriteParamter(col.CsType, _commonUtils.QuoteParamterName($"{col.CsName}{didx}")));
 | 
				
			||||||
						//	_params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}{didx}", col.CsType, val);
 | 
												_params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}{didx}", col.CsType, val);
 | 
				
			||||||
						//}
 | 
											}
 | 
				
			||||||
						++colidx2;
 | 
											++colidx2;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				sb.Append(")");
 | 
									sb.Append(")");
 | 
				
			||||||
				++didx;
 | 
									++didx;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			//if (_source.Count > 1) sb.Append("\r\n SELECT 1 FROM DUAL");
 | 
								if (_source.Count > 1) sb.Append("\r\n SELECT 1 FROM DUAL");
 | 
				
			||||||
			return sb.ToString();
 | 
								return sb.ToString();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ColumnInfo _identCol;
 | 
							ColumnInfo _identCol;
 | 
				
			||||||
		public override long ExecuteIdentity() {
 | 
							internal override long RawExecuteIdentity() {
 | 
				
			||||||
			var sql = this.ToSql();
 | 
								var sql = this.ToSql();
 | 
				
			||||||
			if (string.IsNullOrEmpty(sql)) return 0;
 | 
								if (string.IsNullOrEmpty(sql)) return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -90,7 +97,7 @@ namespace FreeSql.Oracle.Curd {
 | 
				
			|||||||
			_orm.Ado.ExecuteNonQuery(_transaction, CommandType.Text, $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}", _params.Concat(new[] { identParam }).ToArray());
 | 
								_orm.Ado.ExecuteNonQuery(_transaction, CommandType.Text, $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}", _params.Concat(new[] { identParam }).ToArray());
 | 
				
			||||||
			return long.TryParse(string.Concat(identParam.Value), out var trylng) ? trylng : 0;
 | 
								return long.TryParse(string.Concat(identParam.Value), out var trylng) ? trylng : 0;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		async public override Task<long> ExecuteIdentityAsync() {
 | 
							async internal override Task<long> RawExecuteIdentityAsync() {
 | 
				
			||||||
			var sql = this.ToSql();
 | 
								var sql = this.ToSql();
 | 
				
			||||||
			if (string.IsNullOrEmpty(sql)) return 0;
 | 
								if (string.IsNullOrEmpty(sql)) return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -105,53 +112,19 @@ namespace FreeSql.Oracle.Curd {
 | 
				
			|||||||
			return long.TryParse(string.Concat(identParam.Value), out var trylng) ? trylng : 0;
 | 
								return long.TryParse(string.Concat(identParam.Value), out var trylng) ? trylng : 0;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public override List<T1> ExecuteInserted() {
 | 
							internal override List<T1> RawExecuteInserted() {
 | 
				
			||||||
			throw new NotImplementedException();
 | 
								var sql = this.ToSql();
 | 
				
			||||||
 | 
								if (string.IsNullOrEmpty(sql)) return new List<T1>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//			var sql = this.ToSql();
 | 
								this.ExecuteAffrows();
 | 
				
			||||||
//			if (string.IsNullOrEmpty(sql)) return new List<T1>();
 | 
								return _source;
 | 
				
			||||||
 | 
					 | 
				
			||||||
//			var sb = new StringBuilder();
 | 
					 | 
				
			||||||
//			sb.Append(@"declare
 | 
					 | 
				
			||||||
//type v_tp_rec is record(");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//			var colidx = 0;
 | 
					 | 
				
			||||||
//			foreach (var col in _table.Columns.Values) {
 | 
					 | 
				
			||||||
//				if (colidx > 0) sb.Append(", ");
 | 
					 | 
				
			||||||
//				sb.Append(_commonUtils.QuoteSqlName(col.CsName)).Append(" ").Append(_commonUtils.QuoteSqlName(_tableRule?.Invoke(_table.DbName) ?? _table.DbName))).Append(".").Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append("%type");
 | 
					 | 
				
			||||||
//				++colidx;
 | 
					 | 
				
			||||||
//			}
 | 
					 | 
				
			||||||
//			sb.Append(@");
 | 
					 | 
				
			||||||
//type v_tp_tab is table of v_tp_rec;
 | 
					 | 
				
			||||||
//v_tab v_tp_tab;
 | 
					 | 
				
			||||||
//begin
 | 
					 | 
				
			||||||
//");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//			sb.Append(sql).Append(" RETURNING ");
 | 
					 | 
				
			||||||
//			colidx = 0;
 | 
					 | 
				
			||||||
//			foreach (var col in _table.Columns.Values) {
 | 
					 | 
				
			||||||
//				if (colidx > 0) sb.Append(", ");
 | 
					 | 
				
			||||||
//				sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name)));
 | 
					 | 
				
			||||||
//				++colidx;
 | 
					 | 
				
			||||||
//			}
 | 
					 | 
				
			||||||
//			sb.Append(@"bulk collect into v_tab;
 | 
					 | 
				
			||||||
//for i in 1..v_tab.count loop
 | 
					 | 
				
			||||||
//	dbms_output.put_line(");
 | 
					 | 
				
			||||||
//			//v_tab(i).empno||'-'||v_tab(i).ename
 | 
					 | 
				
			||||||
//			colidx = 0;
 | 
					 | 
				
			||||||
//			foreach (var col in _table.Columns.Values) {
 | 
					 | 
				
			||||||
//				if (colidx > 0) sb.Append("||'-'||");
 | 
					 | 
				
			||||||
//				sb.Append("v_tab(i).").Append(_commonUtils.QuoteSqlName(col.CsName));
 | 
					 | 
				
			||||||
//				++colidx;
 | 
					 | 
				
			||||||
//			}
 | 
					 | 
				
			||||||
//			sb.Append(@");
 | 
					 | 
				
			||||||
//end loop;
 | 
					 | 
				
			||||||
//end;
 | 
					 | 
				
			||||||
//");
 | 
					 | 
				
			||||||
//			return _orm.Ado.Query<T1>(_transaction, CommandType.Text, sb.ToString(), _params);
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		public override Task<List<T1>> ExecuteInsertedAsync() {
 | 
							async internal override Task<List<T1>> RawExecuteInsertedAsync() {
 | 
				
			||||||
			throw new NotImplementedException();
 | 
								var sql = this.ToSql();
 | 
				
			||||||
 | 
								if (string.IsNullOrEmpty(sql)) return new List<T1>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								await this.ExecuteAffrowsAsync();
 | 
				
			||||||
 | 
								return _source;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,11 +23,11 @@ namespace FreeSql.Oracle {
 | 
				
			|||||||
			_commonExpression = commonExpression;
 | 
								_commonExpression = commonExpression;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public bool IsAutoSyncStructure { get; set; } = true;
 | 
							public bool IsAutoSyncStructure { get; set; } = false;
 | 
				
			||||||
		public bool IsQuoteSqlName { get; set; } = true;
 | 
					 | 
				
			||||||
		public bool IsSyncStructureToLower { get; set; } = false;
 | 
							public bool IsSyncStructureToLower { get; set; } = false;
 | 
				
			||||||
		public bool IsSyncStructureToUpper { get; set; } = false;
 | 
							public bool IsSyncStructureToUpper { get; set; } = false;
 | 
				
			||||||
		public bool IsConfigEntityFromDbFirst { get; set; } = false;
 | 
							public bool IsConfigEntityFromDbFirst { get; set; } = false;
 | 
				
			||||||
 | 
							public bool IsNoneCommandParameter { get; set; } = false;
 | 
				
			||||||
		public bool IsLazyLoading { get; set; } = false;
 | 
							public bool IsLazyLoading { get; set; } = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		static object _dicCsToDbLock = new object();
 | 
							static object _dicCsToDbLock = new object();
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										11
									
								
								FreeSql/Oracle/OracleExtensions.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								FreeSql/Oracle/OracleExtensions.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					public static class FreeSqlOracleExtensions {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// <summary>
 | 
				
			||||||
 | 
						/// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换
 | 
				
			||||||
 | 
						/// </summary>
 | 
				
			||||||
 | 
						/// <param name="that"></param>
 | 
				
			||||||
 | 
						/// <param name="args"></param>
 | 
				
			||||||
 | 
						/// <returns></returns>
 | 
				
			||||||
 | 
						public static string FormatOracleSQL(this string that, params object[] args) => _oracleAdo.Addslashes(that, args);
 | 
				
			||||||
 | 
						static FreeSql.Oracle.OracleAdo _oracleAdo = new FreeSql.Oracle.OracleAdo();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -14,14 +14,13 @@ namespace FreeSql.Oracle {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		internal override DbParameter AppendParamter(List<DbParameter> _params, string parameterName, Type type, object value) {
 | 
							internal override DbParameter AppendParamter(List<DbParameter> _params, string parameterName, Type type, object value) {
 | 
				
			||||||
			if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}";
 | 
								if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}";
 | 
				
			||||||
			else if (_orm.CodeFirst.IsSyncStructureToLower) parameterName = parameterName.ToLower();
 | 
					 | 
				
			||||||
			var dbtype = (OracleDbType)_orm.CodeFirst.GetDbInfo(type)?.type;
 | 
								var dbtype = (OracleDbType)_orm.CodeFirst.GetDbInfo(type)?.type;
 | 
				
			||||||
			if (dbtype == OracleDbType.Boolean) {
 | 
								if (dbtype == OracleDbType.Boolean) {
 | 
				
			||||||
				if (value == null) value = null;
 | 
									if (value == null) value = null;
 | 
				
			||||||
				else value = (bool)value == true ? 1 : 0;
 | 
									else value = (bool)value == true ? 1 : 0;
 | 
				
			||||||
				dbtype = OracleDbType.Int16;
 | 
									dbtype = OracleDbType.Int16;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			var ret = new OracleParameter { ParameterName = $":{parameterName}", OracleDbType = dbtype, Value = value };
 | 
								var ret = new OracleParameter { ParameterName = QuoteParamterName(parameterName), OracleDbType = dbtype, Value = value };
 | 
				
			||||||
			_params?.Add(ret);
 | 
								_params?.Add(ret);
 | 
				
			||||||
			return ret;
 | 
								return ret;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -48,7 +47,7 @@ namespace FreeSql.Oracle {
 | 
				
			|||||||
		internal override string QuoteWriteParamter(Type type, string paramterName) => paramterName;
 | 
							internal override string QuoteWriteParamter(Type type, string paramterName) => paramterName;
 | 
				
			||||||
		internal override string QuoteReadColumn(Type type, string columnName) => columnName;
 | 
							internal override string QuoteReadColumn(Type type, string columnName) => columnName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		internal override string GetNoneParamaterSqlValue(Type type, object value) {
 | 
							internal override string GetNoneParamaterSqlValue(List<DbParameter> specialParams, Type type, object value) {
 | 
				
			||||||
			if (value == null) return "NULL";
 | 
								if (value == null) return "NULL";
 | 
				
			||||||
			if (type == typeof(byte[])) {
 | 
								if (type == typeof(byte[])) {
 | 
				
			||||||
				var bytes = value as byte[];
 | 
									var bytes = value as byte[];
 | 
				
			||||||
@@ -61,7 +60,5 @@ namespace FreeSql.Oracle {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
			return FormatSql("{0}", value, 1);
 | 
								return FormatSql("{0}", value, 1);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					 | 
				
			||||||
		internal override string DbName => "Oracle";
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,7 +12,15 @@ namespace FreeSql.PostgreSQL.Curd {
 | 
				
			|||||||
			: base(orm, commonUtils, commonExpression) {
 | 
								: base(orm, commonUtils, commonExpression) {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public override long ExecuteIdentity() {
 | 
							public override int ExecuteAffrows() => base.SplitExecuteAffrows(5000, 3000);
 | 
				
			||||||
 | 
							public override Task<int> ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(5000, 3000);
 | 
				
			||||||
 | 
							public override long ExecuteIdentity() => base.SplitExecuteIdentity(5000, 3000);
 | 
				
			||||||
 | 
							public override Task<long> ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(5000, 3000);
 | 
				
			||||||
 | 
							public override List<T1> ExecuteInserted() => base.SplitExecuteInserted(5000, 3000);
 | 
				
			||||||
 | 
							public override Task<List<T1>> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(5000, 3000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							internal override long RawExecuteIdentity() {
 | 
				
			||||||
			var sql = this.ToSql();
 | 
								var sql = this.ToSql();
 | 
				
			||||||
			if (string.IsNullOrEmpty(sql)) return 0;
 | 
								if (string.IsNullOrEmpty(sql)) return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -23,7 +31,7 @@ namespace FreeSql.PostgreSQL.Curd {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
			return long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_transaction, CommandType.Text, string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)), _params)), out var trylng) ? trylng : 0;
 | 
								return long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_transaction, CommandType.Text, string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)), _params)), out var trylng) ? trylng : 0;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		async public override Task<long> ExecuteIdentityAsync() {
 | 
							async internal override Task<long> RawExecuteIdentityAsync() {
 | 
				
			||||||
			var sql = this.ToSql();
 | 
								var sql = this.ToSql();
 | 
				
			||||||
			if (string.IsNullOrEmpty(sql)) return 0;
 | 
								if (string.IsNullOrEmpty(sql)) return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -35,7 +43,7 @@ namespace FreeSql.PostgreSQL.Curd {
 | 
				
			|||||||
			return long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_transaction, CommandType.Text, string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)), _params)), out var trylng) ? trylng : 0;
 | 
								return long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_transaction, CommandType.Text, string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)), _params)), out var trylng) ? trylng : 0;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public override List<T1> ExecuteInserted() {
 | 
							internal override List<T1> RawExecuteInserted() {
 | 
				
			||||||
			var sql = this.ToSql();
 | 
								var sql = this.ToSql();
 | 
				
			||||||
			if (string.IsNullOrEmpty(sql)) return new List<T1>();
 | 
								if (string.IsNullOrEmpty(sql)) return new List<T1>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -50,7 +58,7 @@ namespace FreeSql.PostgreSQL.Curd {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
			return _orm.Ado.Query<T1>(_transaction, CommandType.Text, sb.ToString(), _params);
 | 
								return _orm.Ado.Query<T1>(_transaction, CommandType.Text, sb.ToString(), _params);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		async public override Task<List<T1>> ExecuteInsertedAsync() {
 | 
							async internal override Task<List<T1>> RawExecuteInsertedAsync() {
 | 
				
			||||||
			var sql = this.ToSql();
 | 
								var sql = this.ToSql();
 | 
				
			||||||
			if (string.IsNullOrEmpty(sql)) return new List<T1>();
 | 
								if (string.IsNullOrEmpty(sql)) return new List<T1>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,10 +28,11 @@ namespace FreeSql.PostgreSQL {
 | 
				
			|||||||
			_commonExpression = commonExpression;
 | 
								_commonExpression = commonExpression;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public bool IsAutoSyncStructure { get; set; } = true;
 | 
							public bool IsAutoSyncStructure { get; set; } = false;
 | 
				
			||||||
		public bool IsSyncStructureToLower { get; set; } = false;
 | 
							public bool IsSyncStructureToLower { get; set; } = false;
 | 
				
			||||||
		public bool IsSyncStructureToUpper { get; set; } = false;
 | 
							public bool IsSyncStructureToUpper { get; set; } = false;
 | 
				
			||||||
		public bool IsConfigEntityFromDbFirst { get; set; } = false;
 | 
							public bool IsConfigEntityFromDbFirst { get; set; } = false;
 | 
				
			||||||
 | 
							public bool IsNoneCommandParameter { get; set; } = false;
 | 
				
			||||||
		public bool IsLazyLoading { get; set; } = false;
 | 
							public bool IsLazyLoading { get; set; } = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		static object _dicCsToDbLock = new object();
 | 
							static object _dicCsToDbLock = new object();
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										11
									
								
								FreeSql/PostgreSQL/PostgreSQLExtensions.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								FreeSql/PostgreSQL/PostgreSQLExtensions.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					public static class FreeSqlPostgreSQLExtensions {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// <summary>
 | 
				
			||||||
 | 
						/// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换
 | 
				
			||||||
 | 
						/// </summary>
 | 
				
			||||||
 | 
						/// <param name="that"></param>
 | 
				
			||||||
 | 
						/// <param name="args"></param>
 | 
				
			||||||
 | 
						/// <returns></returns>
 | 
				
			||||||
 | 
						public static string FormatPostgreSQL(this string that, params object[] args) => _postgresqlAdo.Addslashes(that, args);
 | 
				
			||||||
 | 
						static FreeSql.PostgreSQL.PostgreSQLAdo _postgresqlAdo = new FreeSql.PostgreSQL.PostgreSQLAdo();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -4,14 +4,50 @@ using FreeSql.PostgreSQL.Curd;
 | 
				
			|||||||
using Microsoft.Extensions.Caching.Distributed;
 | 
					using Microsoft.Extensions.Caching.Distributed;
 | 
				
			||||||
using Microsoft.Extensions.Configuration;
 | 
					using Microsoft.Extensions.Configuration;
 | 
				
			||||||
using Microsoft.Extensions.Logging;
 | 
					using Microsoft.Extensions.Logging;
 | 
				
			||||||
 | 
					using Newtonsoft.Json.Linq;
 | 
				
			||||||
 | 
					using Npgsql.LegacyPostgis;
 | 
				
			||||||
 | 
					using NpgsqlTypes;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Data.Common;
 | 
					using System.Data.Common;
 | 
				
			||||||
 | 
					using System.Net;
 | 
				
			||||||
 | 
					using System.Net.NetworkInformation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace FreeSql.PostgreSQL {
 | 
					namespace FreeSql.PostgreSQL {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class PostgreSQLProvider : IFreeSql {
 | 
						class PostgreSQLProvider : IFreeSql {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							static PostgreSQLProvider() {
 | 
				
			||||||
 | 
								Utils.dicExecuteArrayRowReadClassOrTuple.Add(typeof(BitArray), true);
 | 
				
			||||||
 | 
								Utils.dicExecuteArrayRowReadClassOrTuple.Add(typeof(NpgsqlPoint), true);
 | 
				
			||||||
 | 
								Utils.dicExecuteArrayRowReadClassOrTuple.Add(typeof(NpgsqlLine), true);
 | 
				
			||||||
 | 
								Utils.dicExecuteArrayRowReadClassOrTuple.Add(typeof(NpgsqlLSeg), true);
 | 
				
			||||||
 | 
								Utils.dicExecuteArrayRowReadClassOrTuple.Add(typeof(NpgsqlBox), true);
 | 
				
			||||||
 | 
								Utils.dicExecuteArrayRowReadClassOrTuple.Add(typeof(NpgsqlPath), true);
 | 
				
			||||||
 | 
								Utils.dicExecuteArrayRowReadClassOrTuple.Add(typeof(NpgsqlPolygon), true);
 | 
				
			||||||
 | 
								Utils.dicExecuteArrayRowReadClassOrTuple.Add(typeof(NpgsqlCircle), true);
 | 
				
			||||||
 | 
								Utils.dicExecuteArrayRowReadClassOrTuple.Add(typeof((IPAddress Address, int Subnet)), true);
 | 
				
			||||||
 | 
								Utils.dicExecuteArrayRowReadClassOrTuple.Add(typeof(IPAddress), true);
 | 
				
			||||||
 | 
								Utils.dicExecuteArrayRowReadClassOrTuple.Add(typeof(PhysicalAddress), true);
 | 
				
			||||||
 | 
								Utils.dicExecuteArrayRowReadClassOrTuple.Add(typeof(NpgsqlRange<int>), true);
 | 
				
			||||||
 | 
								Utils.dicExecuteArrayRowReadClassOrTuple.Add(typeof(NpgsqlRange<long>), true);
 | 
				
			||||||
 | 
								Utils.dicExecuteArrayRowReadClassOrTuple.Add(typeof(NpgsqlRange<decimal>), true);
 | 
				
			||||||
 | 
								Utils.dicExecuteArrayRowReadClassOrTuple.Add(typeof(NpgsqlRange<DateTime>), true);
 | 
				
			||||||
 | 
								Utils.dicExecuteArrayRowReadClassOrTuple.Add(typeof(PostgisPoint), true);
 | 
				
			||||||
 | 
								Utils.dicExecuteArrayRowReadClassOrTuple.Add(typeof(PostgisLineString), true);
 | 
				
			||||||
 | 
								Utils.dicExecuteArrayRowReadClassOrTuple.Add(typeof(PostgisPolygon), true);
 | 
				
			||||||
 | 
								Utils.dicExecuteArrayRowReadClassOrTuple.Add(typeof(PostgisMultiPoint), true);
 | 
				
			||||||
 | 
								Utils.dicExecuteArrayRowReadClassOrTuple.Add(typeof(PostgisMultiLineString), true);
 | 
				
			||||||
 | 
								Utils.dicExecuteArrayRowReadClassOrTuple.Add(typeof(PostgisMultiPolygon), true);
 | 
				
			||||||
 | 
								Utils.dicExecuteArrayRowReadClassOrTuple.Add(typeof(PostgisGeometry), true);
 | 
				
			||||||
 | 
								Utils.dicExecuteArrayRowReadClassOrTuple.Add(typeof(PostgisGeometryCollection), true);
 | 
				
			||||||
 | 
								Utils.dicExecuteArrayRowReadClassOrTuple.Add(typeof(Dictionary<string, string>), true);
 | 
				
			||||||
 | 
								Utils.dicExecuteArrayRowReadClassOrTuple.Add(typeof(JToken), true);
 | 
				
			||||||
 | 
								Utils.dicExecuteArrayRowReadClassOrTuple.Add(typeof(JObject), true);
 | 
				
			||||||
 | 
								Utils.dicExecuteArrayRowReadClassOrTuple.Add(typeof(JArray), true);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public ISelect<T1> Select<T1>() where T1 : class => new PostgreSQLSelect<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, null);
 | 
							public ISelect<T1> Select<T1>() where T1 : class => new PostgreSQLSelect<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, null);
 | 
				
			||||||
		public ISelect<T1> Select<T1>(object dywhere) where T1 : class => new PostgreSQLSelect<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere);
 | 
							public ISelect<T1> Select<T1>(object dywhere) where T1 : class => new PostgreSQLSelect<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere);
 | 
				
			||||||
		public IInsert<T1> Insert<T1>() where T1 : class => new PostgreSQLInsert<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression);
 | 
							public IInsert<T1> Insert<T1>() where T1 : class => new PostgreSQLInsert<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,12 @@
 | 
				
			|||||||
using FreeSql.Internal;
 | 
					using FreeSql.Internal;
 | 
				
			||||||
using Newtonsoft.Json.Linq;
 | 
					using Newtonsoft.Json.Linq;
 | 
				
			||||||
using Npgsql;
 | 
					using Npgsql;
 | 
				
			||||||
 | 
					using Npgsql.LegacyPostgis;
 | 
				
			||||||
using NpgsqlTypes;
 | 
					using NpgsqlTypes;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Collections.Concurrent;
 | 
				
			||||||
using System.Data.Common;
 | 
					using System.Data.Common;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
using System.Net;
 | 
					using System.Net;
 | 
				
			||||||
@@ -68,9 +71,8 @@ namespace FreeSql.PostgreSQL {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		internal override DbParameter AppendParamter(List<DbParameter> _params, string parameterName, Type type, object value) {
 | 
							internal override DbParameter AppendParamter(List<DbParameter> _params, string parameterName, Type type, object value) {
 | 
				
			||||||
			if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}";
 | 
								if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}";
 | 
				
			||||||
			else if (_orm.CodeFirst.IsSyncStructureToLower) parameterName = parameterName.ToLower();
 | 
					 | 
				
			||||||
			if (value != null) value = getParamterValue(type, value);
 | 
								if (value != null) value = getParamterValue(type, value);
 | 
				
			||||||
			var ret = new NpgsqlParameter { ParameterName = $"@{parameterName}", Value = value };
 | 
								var ret = new NpgsqlParameter { ParameterName = QuoteParamterName(parameterName), Value = value };
 | 
				
			||||||
			//if (value.GetType().IsEnum || value.GetType().GenericTypeArguments.FirstOrDefault()?.IsEnum == true) {
 | 
								//if (value.GetType().IsEnum || value.GetType().GenericTypeArguments.FirstOrDefault()?.IsEnum == true) {
 | 
				
			||||||
			//	ret.DataTypeName = "";
 | 
								//	ret.DataTypeName = "";
 | 
				
			||||||
			//} else {
 | 
								//} else {
 | 
				
			||||||
@@ -104,13 +106,18 @@ namespace FreeSql.PostgreSQL {
 | 
				
			|||||||
		internal override string QuoteWriteParamter(Type type, string paramterName) => paramterName;
 | 
							internal override string QuoteWriteParamter(Type type, string paramterName) => paramterName;
 | 
				
			||||||
		internal override string QuoteReadColumn(Type type, string columnName) => columnName;
 | 
							internal override string QuoteReadColumn(Type type, string columnName) => columnName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		internal override string GetNoneParamaterSqlValue(Type type, object value) {
 | 
							static ConcurrentDictionary<Type, bool> _dicIsAssignableFromPostgisGeometry = new ConcurrentDictionary<Type, bool>();
 | 
				
			||||||
 | 
							internal override string GetNoneParamaterSqlValue(List<DbParameter> specialParams, Type type, object value) {
 | 
				
			||||||
			if (value == null) return "NULL";
 | 
								if (value == null) return "NULL";
 | 
				
			||||||
 | 
								if (_dicIsAssignableFromPostgisGeometry.GetOrAdd(type, t2 => typeof(PostgisGeometry).IsAssignableFrom(type.IsArray ? type.GetElementType() : type))) {
 | 
				
			||||||
 | 
									var pam = AppendParamter(specialParams, null, type, value);
 | 
				
			||||||
 | 
									return pam.ParameterName;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			value = getParamterValue(type, value);
 | 
								value = getParamterValue(type, value);
 | 
				
			||||||
			var type2 = value.GetType();
 | 
								var type2 = value.GetType();
 | 
				
			||||||
			if (type2 == typeof(byte[])) {
 | 
								if (type2 == typeof(byte[])) {
 | 
				
			||||||
				var bytes = value as byte[];
 | 
									var bytes = value as byte[];
 | 
				
			||||||
				var sb = new StringBuilder().Append("E'\\x");
 | 
									var sb = new StringBuilder().Append("'\\x");
 | 
				
			||||||
				foreach (var vc in bytes) {
 | 
									foreach (var vc in bytes) {
 | 
				
			||||||
					if (vc < 10) sb.Append("0");
 | 
										if (vc < 10) sb.Append("0");
 | 
				
			||||||
					sb.Append(vc.ToString("X"));
 | 
										sb.Append(vc.ToString("X"));
 | 
				
			||||||
@@ -118,11 +125,33 @@ namespace FreeSql.PostgreSQL {
 | 
				
			|||||||
				return sb.Append("'").ToString(); //val = Encoding.UTF8.GetString(val as byte[]);
 | 
									return sb.Append("'").ToString(); //val = Encoding.UTF8.GetString(val as byte[]);
 | 
				
			||||||
			} else if (type2 == typeof(TimeSpan) || type2 == typeof(TimeSpan?)) {
 | 
								} else if (type2 == typeof(TimeSpan) || type2 == typeof(TimeSpan?)) {
 | 
				
			||||||
				var ts = (TimeSpan)value;
 | 
									var ts = (TimeSpan)value;
 | 
				
			||||||
				value = $"{ts.Hours}:{ts.Minutes}:{ts.Seconds}";
 | 
									return $"'{Math.Min(24, (int)Math.Floor(ts.TotalHours))}:{ts.Minutes}:{ts.Seconds}'";
 | 
				
			||||||
 | 
								} else if (value is Array) {
 | 
				
			||||||
 | 
									var valueArr = value as Array;
 | 
				
			||||||
 | 
									var eleType = type2.GetElementType();
 | 
				
			||||||
 | 
									var len = valueArr.GetLength(0);
 | 
				
			||||||
 | 
									var sb = new StringBuilder().Append("ARRAY[");
 | 
				
			||||||
 | 
									for (var a = 0; a < len; a++) {
 | 
				
			||||||
 | 
										var item = valueArr.GetValue(a);
 | 
				
			||||||
 | 
										if (a > 0) sb.Append(",");
 | 
				
			||||||
 | 
										sb.Append(GetNoneParamaterSqlValue(specialParams, eleType, item));
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									sb.Append("]");
 | 
				
			||||||
 | 
									var dbinfo = _orm.CodeFirst.GetDbInfo(type);
 | 
				
			||||||
 | 
									if (dbinfo.HasValue) sb.Append("::").Append(dbinfo.Value.dbtype);
 | 
				
			||||||
 | 
									return sb.ToString();
 | 
				
			||||||
 | 
								} else if (type2 == typeof(BitArray)) {
 | 
				
			||||||
 | 
									return $"'{(value as BitArray).To1010()}'";
 | 
				
			||||||
 | 
								} else if (type2 == typeof(NpgsqlLine) || type2 == typeof(NpgsqlLine?)) {
 | 
				
			||||||
 | 
									var line = value.ToString();
 | 
				
			||||||
 | 
									return line == "{0,0,0}" ? "'{0,-1,-1}'" : $"'{line}'";
 | 
				
			||||||
 | 
								} else if (type2 == typeof((IPAddress Address, int Subnet)) || type2 == typeof((IPAddress Address, int Subnet)?)) {
 | 
				
			||||||
 | 
									var cidr = ((IPAddress Address, int Subnet))value;
 | 
				
			||||||
 | 
									return $"'{cidr.Address}/{cidr.Subnet}'";
 | 
				
			||||||
 | 
								} else if (dicGetParamterValue.ContainsKey(type2.FullName)) {
 | 
				
			||||||
 | 
									value = string.Concat(value);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return FormatSql("{0}", value, 1);
 | 
								return FormatSql("{0}", value, 1);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					 | 
				
			||||||
		internal override string DbName => "PostgreSQL";
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,46 +14,28 @@ namespace FreeSql.SqlServer.Curd {
 | 
				
			|||||||
			: base(orm, commonUtils, commonExpression) {
 | 
								: base(orm, commonUtils, commonExpression) {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public override long ExecuteIdentity() {
 | 
							public override int ExecuteAffrows() => base.SplitExecuteAffrows(1000, 2100);
 | 
				
			||||||
			//if (_source?.Count > 999) {
 | 
							public override Task<int> ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(1000, 2100);
 | 
				
			||||||
			//	List<IInsert<T1>> inserts = new List<IInsert<T1>>();
 | 
							public override long ExecuteIdentity() => base.SplitExecuteIdentity(1000, 2100);
 | 
				
			||||||
			//	var idx = 0;
 | 
							public override Task<long> ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(1000, 2100);
 | 
				
			||||||
			//	while (idx < _source.Count) {
 | 
							public override List<T1> ExecuteInserted() => base.SplitExecuteInserted(1000, 2100);
 | 
				
			||||||
			//		var count = Math.Min(_source.Count, idx + 999) - idx;
 | 
							public override Task<List<T1>> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(1000, 2100);
 | 
				
			||||||
			//		var insert = _orm.Insert<T1>().AppendData(_source.GetRange(idx, count));
 | 
					
 | 
				
			||||||
			//		_
 | 
					
 | 
				
			||||||
			//		inserts.Add(insert);
 | 
							internal override long RawExecuteIdentity() {
 | 
				
			||||||
			//		idx += 999;
 | 
					 | 
				
			||||||
			//	}
 | 
					 | 
				
			||||||
			//	Object<DbConnection> conn = null;
 | 
					 | 
				
			||||||
			//	var trans = _transaction;
 | 
					 | 
				
			||||||
			//	if (_transaction == null) {
 | 
					 | 
				
			||||||
			//		conn = _orm.Ado.MasterPool.Get();
 | 
					 | 
				
			||||||
			//		trans = conn.Value.BeginTransaction();
 | 
					 | 
				
			||||||
			//	}
 | 
					 | 
				
			||||||
			//	try {
 | 
					 | 
				
			||||||
			//		for (var a = 0; a < inserts.Count; a++) {
 | 
					 | 
				
			||||||
			//			inserts[a].WithTransaction(trans)
 | 
					 | 
				
			||||||
			//		}
 | 
					 | 
				
			||||||
			//		if (_transaction == null) trans.Commit();
 | 
					 | 
				
			||||||
			//	} catch {
 | 
					 | 
				
			||||||
			//		if (_transaction == null) trans.Rollback();
 | 
					 | 
				
			||||||
			//		throw;
 | 
					 | 
				
			||||||
			//	}
 | 
					 | 
				
			||||||
			//}
 | 
					 | 
				
			||||||
			var sql = this.ToSql();
 | 
								var sql = this.ToSql();
 | 
				
			||||||
			if (string.IsNullOrEmpty(sql)) return 0;
 | 
								if (string.IsNullOrEmpty(sql)) return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_transaction, CommandType.Text, string.Concat(sql, "; SELECT SCOPE_IDENTITY();"), _params)), out var trylng) ? trylng : 0;
 | 
								return long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_transaction, CommandType.Text, string.Concat(sql, "; SELECT SCOPE_IDENTITY();"), _params)), out var trylng) ? trylng : 0;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		async public override Task<long> ExecuteIdentityAsync() {
 | 
							async internal override Task<long> RawExecuteIdentityAsync() {
 | 
				
			||||||
			var sql = this.ToSql();
 | 
								var sql = this.ToSql();
 | 
				
			||||||
			if (string.IsNullOrEmpty(sql)) return 0;
 | 
								if (string.IsNullOrEmpty(sql)) return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_transaction, CommandType.Text, string.Concat(sql, "; SELECT SCOPE_IDENTITY();"), _params)), out var trylng) ? trylng : 0;
 | 
								return long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_transaction, CommandType.Text, string.Concat(sql, "; SELECT SCOPE_IDENTITY();"), _params)), out var trylng) ? trylng : 0;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public override List<T1> ExecuteInserted() {
 | 
							internal override List<T1> RawExecuteInserted() {
 | 
				
			||||||
			var sql = this.ToSql();
 | 
								var sql = this.ToSql();
 | 
				
			||||||
			if (string.IsNullOrEmpty(sql)) return new List<T1>();
 | 
								if (string.IsNullOrEmpty(sql)) return new List<T1>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -73,7 +55,7 @@ namespace FreeSql.SqlServer.Curd {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			return _orm.Ado.Query<T1>(_transaction, CommandType.Text, sb.ToString(), _params);
 | 
								return _orm.Ado.Query<T1>(_transaction, CommandType.Text, sb.ToString(), _params);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		async public override Task<List<T1>> ExecuteInsertedAsync() {
 | 
							async internal override Task<List<T1>> RawExecuteInsertedAsync() {
 | 
				
			||||||
			var sql = this.ToSql();
 | 
								var sql = this.ToSql();
 | 
				
			||||||
			if (string.IsNullOrEmpty(sql)) return new List<T1>();
 | 
								if (string.IsNullOrEmpty(sql)) return new List<T1>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,10 +22,11 @@ namespace FreeSql.SqlServer {
 | 
				
			|||||||
			_commonExpression = commonExpression;
 | 
								_commonExpression = commonExpression;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public bool IsAutoSyncStructure { get; set; } = true;
 | 
							public bool IsAutoSyncStructure { get; set; } = false;
 | 
				
			||||||
		public bool IsSyncStructureToLower { get; set; } = false;
 | 
							public bool IsSyncStructureToLower { get; set; } = false;
 | 
				
			||||||
		public bool IsSyncStructureToUpper { get; set; } = false;
 | 
							public bool IsSyncStructureToUpper { get; set; } = false;
 | 
				
			||||||
		public bool IsConfigEntityFromDbFirst { get; set; } = false;
 | 
							public bool IsConfigEntityFromDbFirst { get; set; } = false;
 | 
				
			||||||
 | 
							public bool IsNoneCommandParameter { get; set; } = false;
 | 
				
			||||||
		public bool IsLazyLoading { get; set; } = false;
 | 
							public bool IsLazyLoading { get; set; } = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		static object _dicCsToDbLock = new object();
 | 
							static object _dicCsToDbLock = new object();
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										11
									
								
								FreeSql/SqlServer/SqlServerExtensions.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								FreeSql/SqlServer/SqlServerExtensions.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					public static class FreeSqlSqlServerExtensions {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// <summary>
 | 
				
			||||||
 | 
						/// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换
 | 
				
			||||||
 | 
						/// </summary>
 | 
				
			||||||
 | 
						/// <param name="that"></param>
 | 
				
			||||||
 | 
						/// <param name="args"></param>
 | 
				
			||||||
 | 
						/// <returns></returns>
 | 
				
			||||||
 | 
						public static string FormatSqlServer(this string that, params object[] args) => _sqlserverAdo.Addslashes(that, args);
 | 
				
			||||||
 | 
						static FreeSql.SqlServer.SqlServerAdo _sqlserverAdo = new FreeSql.SqlServer.SqlServerAdo();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -17,9 +17,8 @@ namespace FreeSql.SqlServer {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		internal override DbParameter AppendParamter(List<DbParameter> _params, string parameterName, Type type, object value) {
 | 
							internal override DbParameter AppendParamter(List<DbParameter> _params, string parameterName, Type type, object value) {
 | 
				
			||||||
			if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}";
 | 
								if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}";
 | 
				
			||||||
			else if (_orm.CodeFirst.IsSyncStructureToLower) parameterName = parameterName.ToLower();
 | 
					 | 
				
			||||||
			if (value?.Equals(DateTime.MinValue) == true) value = new DateTime(1970, 1, 1);
 | 
								if (value?.Equals(DateTime.MinValue) == true) value = new DateTime(1970, 1, 1);
 | 
				
			||||||
			var ret = new SqlParameter { ParameterName = $"@{parameterName}", Value = value };
 | 
								var ret = new SqlParameter { ParameterName = QuoteParamterName(parameterName), Value = value };
 | 
				
			||||||
			var tp = _orm.CodeFirst.GetDbInfo(type)?.type;
 | 
								var tp = _orm.CodeFirst.GetDbInfo(type)?.type;
 | 
				
			||||||
			if (tp != null) ret.SqlDbType = (SqlDbType)tp.Value;
 | 
								if (tp != null) ret.SqlDbType = (SqlDbType)tp.Value;
 | 
				
			||||||
			_params?.Add(ret);
 | 
								_params?.Add(ret);
 | 
				
			||||||
@@ -45,7 +44,7 @@ namespace FreeSql.SqlServer {
 | 
				
			|||||||
		internal override string QuoteWriteParamter(Type type, string paramterName) => paramterName;
 | 
							internal override string QuoteWriteParamter(Type type, string paramterName) => paramterName;
 | 
				
			||||||
		internal override string QuoteReadColumn(Type type, string columnName) => columnName;
 | 
							internal override string QuoteReadColumn(Type type, string columnName) => columnName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		internal override string GetNoneParamaterSqlValue(Type type, object value) {
 | 
							internal override string GetNoneParamaterSqlValue(List<DbParameter> specialParams, Type type, object value) {
 | 
				
			||||||
			if (value == null) return "NULL";
 | 
								if (value == null) return "NULL";
 | 
				
			||||||
			if (type == typeof(byte[])) {
 | 
								if (type == typeof(byte[])) {
 | 
				
			||||||
				var bytes = value as byte[];
 | 
									var bytes = value as byte[];
 | 
				
			||||||
@@ -61,7 +60,5 @@ namespace FreeSql.SqlServer {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
			return FormatSql("{0}", value, 1);
 | 
								return FormatSql("{0}", value, 1);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					 | 
				
			||||||
		internal override string DbName => "SqlServer";
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,6 +2,7 @@
 | 
				
			|||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Data;
 | 
					using System.Data;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
using System.Text;
 | 
					using System.Text;
 | 
				
			||||||
using System.Threading.Tasks;
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -12,24 +13,39 @@ namespace FreeSql.Sqlite.Curd {
 | 
				
			|||||||
			: base(orm, commonUtils, commonExpression) {
 | 
								: base(orm, commonUtils, commonExpression) {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public override long ExecuteIdentity() {
 | 
							public override int ExecuteAffrows() => base.SplitExecuteAffrows(5000, 999);
 | 
				
			||||||
 | 
							public override Task<int> ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(5000, 999);
 | 
				
			||||||
 | 
							public override long ExecuteIdentity() => base.SplitExecuteIdentity(5000, 999);
 | 
				
			||||||
 | 
							public override Task<long> ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(5000, 999);
 | 
				
			||||||
 | 
							public override List<T1> ExecuteInserted() => base.SplitExecuteInserted(5000, 999);
 | 
				
			||||||
 | 
							public override Task<List<T1>> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(5000, 999);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							internal override long RawExecuteIdentity() {
 | 
				
			||||||
			var sql = this.ToSql();
 | 
								var sql = this.ToSql();
 | 
				
			||||||
			if (string.IsNullOrEmpty(sql)) return 0;
 | 
								if (string.IsNullOrEmpty(sql)) return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_transaction, CommandType.Text, string.Concat(sql, "; SELECT last_insert_rowid();"), _params)), out var trylng) ? trylng : 0;
 | 
								return long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_transaction, CommandType.Text, string.Concat(sql, "; SELECT last_insert_rowid();"), _params)), out var trylng) ? trylng : 0;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		async public override Task<long> ExecuteIdentityAsync() {
 | 
							async internal override Task<long> RawExecuteIdentityAsync() {
 | 
				
			||||||
			var sql = this.ToSql();
 | 
								var sql = this.ToSql();
 | 
				
			||||||
			if (string.IsNullOrEmpty(sql)) return 0;
 | 
								if (string.IsNullOrEmpty(sql)) return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_transaction, CommandType.Text, string.Concat(sql, "; SELECT last_insert_rowid();"), _params)), out var trylng) ? trylng : 0;
 | 
								return long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_transaction, CommandType.Text, string.Concat(sql, "; SELECT last_insert_rowid();"), _params)), out var trylng) ? trylng : 0;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							internal override List<T1> RawExecuteInserted() {
 | 
				
			||||||
 | 
								var sql = this.ToSql();
 | 
				
			||||||
 | 
								if (string.IsNullOrEmpty(sql)) return new List<T1>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public override List<T1> ExecuteInserted() {
 | 
								this.ExecuteAffrows();
 | 
				
			||||||
			throw new NotImplementedException();
 | 
								return _source;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		public override Task<List<T1>> ExecuteInsertedAsync() {
 | 
							async internal override Task<List<T1>> RawExecuteInsertedAsync() {
 | 
				
			||||||
			throw new NotImplementedException();
 | 
								var sql = this.ToSql();
 | 
				
			||||||
 | 
								if (string.IsNullOrEmpty(sql)) return new List<T1>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								await this.ExecuteAffrowsAsync();
 | 
				
			||||||
 | 
								return _source;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,10 +22,11 @@ namespace FreeSql.Sqlite {
 | 
				
			|||||||
			_commonExpression = commonExpression;
 | 
								_commonExpression = commonExpression;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public bool IsAutoSyncStructure { get; set; } = true;
 | 
							public bool IsAutoSyncStructure { get; set; } = false;
 | 
				
			||||||
		public bool IsSyncStructureToLower { get; set; } = false;
 | 
							public bool IsSyncStructureToLower { get; set; } = false;
 | 
				
			||||||
		public bool IsSyncStructureToUpper { get; set; } = false;
 | 
							public bool IsSyncStructureToUpper { get; set; } = false;
 | 
				
			||||||
		public bool IsConfigEntityFromDbFirst { get; set; } = false;
 | 
							public bool IsConfigEntityFromDbFirst { get; set; } = false;
 | 
				
			||||||
 | 
							public bool IsNoneCommandParameter { get; set; } = false;
 | 
				
			||||||
		public bool IsLazyLoading { get; set; } = false;
 | 
							public bool IsLazyLoading { get; set; } = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		static object _dicCsToDbLock = new object();
 | 
							static object _dicCsToDbLock = new object();
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										11
									
								
								FreeSql/Sqlite/SqliteExtensions.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								FreeSql/Sqlite/SqliteExtensions.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					public static class FreeSqlSqliteExtensions {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// <summary>
 | 
				
			||||||
 | 
						/// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换
 | 
				
			||||||
 | 
						/// </summary>
 | 
				
			||||||
 | 
						/// <param name="that"></param>
 | 
				
			||||||
 | 
						/// <param name="args"></param>
 | 
				
			||||||
 | 
						/// <returns></returns>
 | 
				
			||||||
 | 
						public static string FormatSqlite (this string that, params object[] args) => _sqliteAdo.Addslashes(that, args);
 | 
				
			||||||
 | 
						static FreeSql.Sqlite.SqliteAdo _sqliteAdo = new FreeSql.Sqlite.SqliteAdo();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -15,7 +15,6 @@ namespace FreeSql.Sqlite {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		internal override DbParameter AppendParamter(List<DbParameter> _params, string parameterName, Type type, object value) {
 | 
							internal override DbParameter AppendParamter(List<DbParameter> _params, string parameterName, Type type, object value) {
 | 
				
			||||||
			if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}";
 | 
								if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}";
 | 
				
			||||||
			else if (_orm.CodeFirst.IsSyncStructureToLower) parameterName = parameterName.ToLower();
 | 
					 | 
				
			||||||
			var dbtype = (DbType)_orm.CodeFirst.GetDbInfo(type)?.type;
 | 
								var dbtype = (DbType)_orm.CodeFirst.GetDbInfo(type)?.type;
 | 
				
			||||||
			switch (dbtype) {
 | 
								switch (dbtype) {
 | 
				
			||||||
				case DbType.Guid:
 | 
									case DbType.Guid:
 | 
				
			||||||
@@ -29,7 +28,7 @@ namespace FreeSql.Sqlite {
 | 
				
			|||||||
					dbtype = DbType.Int64;
 | 
										dbtype = DbType.Int64;
 | 
				
			||||||
					break;
 | 
										break;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			var ret = new SQLiteParameter { ParameterName = $"@{parameterName}", DbType = dbtype, Value = value };
 | 
								var ret = new SQLiteParameter { ParameterName = QuoteParamterName(parameterName), DbType = dbtype, Value = value };
 | 
				
			||||||
			_params?.Add(ret);
 | 
								_params?.Add(ret);
 | 
				
			||||||
			return ret;
 | 
								return ret;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -63,12 +62,10 @@ namespace FreeSql.Sqlite {
 | 
				
			|||||||
		internal override string QuoteWriteParamter(Type type, string paramterName) => paramterName;
 | 
							internal override string QuoteWriteParamter(Type type, string paramterName) => paramterName;
 | 
				
			||||||
		internal override string QuoteReadColumn(Type type, string columnName) => columnName;
 | 
							internal override string QuoteReadColumn(Type type, string columnName) => columnName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		internal override string GetNoneParamaterSqlValue(Type type, object value) {
 | 
							internal override string GetNoneParamaterSqlValue(List<DbParameter> specialParams, Type type, object value) {
 | 
				
			||||||
			if (value == null) return "NULL";
 | 
								if (value == null) return "NULL";
 | 
				
			||||||
			if (type == typeof(byte[])) value = Encoding.UTF8.GetString(value as byte[]);
 | 
								if (type == typeof(byte[])) value = Encoding.UTF8.GetString(value as byte[]);
 | 
				
			||||||
			return FormatSql("{0}", value, 1);
 | 
								return FormatSql("{0}", value, 1);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					 | 
				
			||||||
		internal override string DbName => "Sqlite";
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user