mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 01:05:27 +08:00 
			
		
		
		
	- 增加 KingBaseES 支持数组等类型(参考 PostgreSQL);
This commit is contained in:
		
							
								
								
									
										1541
									
								
								FreeSql/FreeSql.xml
									
									
									
									
									
								
							
							
						
						
									
										1541
									
								
								FreeSql/FreeSql.xml
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -20,7 +20,7 @@
 | 
				
			|||||||
	</PropertyGroup>
 | 
						</PropertyGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	<ItemGroup>
 | 
						<ItemGroup>
 | 
				
			||||||
		<None Include="../../readme.md" Pack="true" PackagePath="\"/>
 | 
							<None Include="../../readme.md" Pack="true" PackagePath="\" />
 | 
				
			||||||
		<None Include="../../logo.png" Pack="true" PackagePath="\" />
 | 
							<None Include="../../logo.png" Pack="true" PackagePath="\" />
 | 
				
			||||||
	</ItemGroup>
 | 
						</ItemGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -32,6 +32,10 @@
 | 
				
			|||||||
		</None>
 | 
							</None>
 | 
				
			||||||
	</ItemGroup>
 | 
						</ItemGroup>
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
 | 
						<ItemGroup>
 | 
				
			||||||
 | 
							<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
 | 
				
			||||||
 | 
						</ItemGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	<ItemGroup>
 | 
						<ItemGroup>
 | 
				
			||||||
		<ProjectReference Include="..\..\FreeSql\FreeSql.csproj" />
 | 
							<ProjectReference Include="..\..\FreeSql\FreeSql.csproj" />
 | 
				
			||||||
	</ItemGroup>
 | 
						</ItemGroup>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,10 +3,13 @@ using FreeSql.Internal.CommonProvider;
 | 
				
			|||||||
using FreeSql.Internal.Model;
 | 
					using FreeSql.Internal.Model;
 | 
				
			||||||
using FreeSql.Internal.ObjectPool;
 | 
					using FreeSql.Internal.ObjectPool;
 | 
				
			||||||
using Kdbndp;
 | 
					using Kdbndp;
 | 
				
			||||||
 | 
					using Newtonsoft.Json.Linq;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections;
 | 
					using System.Collections;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Data.Common;
 | 
					using System.Data.Common;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
using System.Threading;
 | 
					using System.Threading;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace FreeSql.KingbaseES
 | 
					namespace FreeSql.KingbaseES
 | 
				
			||||||
@@ -43,9 +46,10 @@ namespace FreeSql.KingbaseES
 | 
				
			|||||||
        public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn)
 | 
					        public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (param == null) return "NULL";
 | 
					            if (param == null) return "NULL";
 | 
				
			||||||
            if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false))
 | 
					            if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || param is JToken || param is JObject || param is JArray))
 | 
				
			||||||
                param = Utils.GetDataReaderValue(mapType, param);
 | 
					                param = Utils.GetDataReaderValue(mapType, param);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            bool isdic;
 | 
				
			||||||
            if (param is bool || param is bool?)
 | 
					            if (param is bool || param is bool?)
 | 
				
			||||||
                return (bool)param ? "'t'" : "'f'";
 | 
					                return (bool)param ? "'t'" : "'f'";
 | 
				
			||||||
            else if (param is string)
 | 
					            else if (param is string)
 | 
				
			||||||
@@ -62,6 +66,16 @@ namespace FreeSql.KingbaseES
 | 
				
			|||||||
            else if (param is DateTime?)
 | 
					            else if (param is DateTime?)
 | 
				
			||||||
                return AddslashesTypeHandler(typeof(DateTime?), param) ?? string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.ffffff"), "'");
 | 
					                return AddslashesTypeHandler(typeof(DateTime?), param) ?? string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.ffffff"), "'");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if net60
 | 
				
			||||||
 | 
					            else if (param is DateOnly || param is DateOnly?)
 | 
				
			||||||
 | 
					                return AddslashesTypeHandler(typeof(DateOnly), param) ?? string.Concat("'", ((DateOnly)param).ToString("yyyy-MM-dd"), "'");
 | 
				
			||||||
 | 
					            else if (param is TimeOnly || param is TimeOnly?)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var ts = (TimeOnly)param;
 | 
				
			||||||
 | 
					                return $"'{ts.Hour}:{ts.Minute}:{ts.Second}.{ts.Millisecond}'";
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            else if (param is TimeSpan || param is TimeSpan?)
 | 
					            else if (param is TimeSpan || param is TimeSpan?)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var ts = (TimeSpan)param;
 | 
					                var ts = (TimeSpan)param;
 | 
				
			||||||
@@ -69,6 +83,31 @@ namespace FreeSql.KingbaseES
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            else if (param is byte[])
 | 
					            else if (param is byte[])
 | 
				
			||||||
                return $"'\\x{CommonUtils.BytesSqlRaw(param as byte[])}'";
 | 
					                return $"'\\x{CommonUtils.BytesSqlRaw(param as byte[])}'";
 | 
				
			||||||
 | 
					            else if (param is JToken || param is JObject || param is JArray)
 | 
				
			||||||
 | 
					                return string.Concat("'", param.ToString().Replace("'", "''"), "'::jsonb");
 | 
				
			||||||
 | 
					            else if ((isdic = param is Dictionary<string, string>) ||
 | 
				
			||||||
 | 
					                param is IEnumerable<KeyValuePair<string, string>>)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var pgdics = isdic ? param as Dictionary<string, string> :
 | 
				
			||||||
 | 
					                    param as IEnumerable<KeyValuePair<string, string>>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var pghstore = new StringBuilder("'");
 | 
				
			||||||
 | 
					                var pairs = pgdics.ToArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                for (var i = 0; i < pairs.Length; i++)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    if (i != 0) pghstore.Append(",");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    pghstore.AppendFormat("\"{0}\"=>", pairs[i].Key.Replace("'", "''"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if (pairs[i].Value == null)
 | 
				
			||||||
 | 
					                        pghstore.Append("NULL");
 | 
				
			||||||
 | 
					                    else
 | 
				
			||||||
 | 
					                        pghstore.AppendFormat("\"{0}\"", pairs[i].Value.Replace("'", "''"));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return pghstore.Append("'::hstore");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            else if (param is IEnumerable)
 | 
					            else if (param is IEnumerable)
 | 
				
			||||||
                return AddslashesIEnumerable(param, mapType, mapColumn);
 | 
					                return AddslashesIEnumerable(param, mapType, mapColumn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,11 +1,17 @@
 | 
				
			|||||||
using FreeSql.Internal;
 | 
					using FreeSql.Internal;
 | 
				
			||||||
using FreeSql.Internal.Model;
 | 
					using FreeSql.Internal.Model;
 | 
				
			||||||
using KdbndpTypes;
 | 
					using KdbndpTypes;
 | 
				
			||||||
 | 
					using Newtonsoft.Json.Linq;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Data;
 | 
					using System.Data;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Net;
 | 
				
			||||||
 | 
					using System.Net.NetworkInformation;
 | 
				
			||||||
 | 
					using System.Numerics;
 | 
				
			||||||
using System.Text;
 | 
					using System.Text;
 | 
				
			||||||
 | 
					using System.Text.RegularExpressions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace FreeSql.KingbaseES
 | 
					namespace FreeSql.KingbaseES
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -36,22 +42,58 @@ namespace FreeSql.KingbaseES
 | 
				
			|||||||
                { typeof(TimeSpan).FullName, CsToDb.New(KdbndpDbType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, CsToDb.New(KdbndpDbType.Time, "time", "time",false, true, null) },
 | 
					                { typeof(TimeSpan).FullName, CsToDb.New(KdbndpDbType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, CsToDb.New(KdbndpDbType.Time, "time", "time",false, true, null) },
 | 
				
			||||||
                { typeof(DateTime).FullName, CsToDb.New(KdbndpDbType.Timestamp, "timestamp", "timestamp NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, CsToDb.New(KdbndpDbType.Timestamp, "timestamp", "timestamp", false, true, null) },
 | 
					                { typeof(DateTime).FullName, CsToDb.New(KdbndpDbType.Timestamp, "timestamp", "timestamp NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, CsToDb.New(KdbndpDbType.Timestamp, "timestamp", "timestamp", false, true, null) },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if net60
 | 
				
			||||||
 | 
					                { typeof(TimeOnly).FullName, CsToDb.New(KdbndpDbType.Time, "time", "time NOT NULL", false, false, 0) },{ typeof(TimeOnly?).FullName, CsToDb.New(KdbndpDbType.Time, "time", "time", false, true, null) },
 | 
				
			||||||
 | 
					                { typeof(DateOnly).FullName, CsToDb.New(KdbndpDbType.Date, "date", "date NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateOnly?).FullName, CsToDb.New(KdbndpDbType.Date, "date", "date", false, true, null) },
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                { typeof(bool).FullName, CsToDb.New(KdbndpDbType.Boolean, "bool","bool NOT NULL", null, false, false) },{ typeof(bool?).FullName, CsToDb.New(KdbndpDbType.Boolean, "bool","bool", null, true, null) },
 | 
					                { typeof(bool).FullName, CsToDb.New(KdbndpDbType.Boolean, "bool","bool NOT NULL", null, false, false) },{ typeof(bool?).FullName, CsToDb.New(KdbndpDbType.Boolean, "bool","bool", null, true, null) },
 | 
				
			||||||
                { typeof(Byte[]).FullName, CsToDb.New(KdbndpDbType.Bytea, "bytea", "bytea", false, null, new byte[0]) },
 | 
					                { typeof(Byte[]).FullName, CsToDb.New(KdbndpDbType.Bytea, "bytea", "bytea", false, null, new byte[0]) },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                { typeof(BitArray).FullName, CsToDb.New(KdbndpDbType.Varbit, "varbit", "varbit(64)", false, null, new BitArray(new byte[64])) },
 | 
				
			||||||
 | 
					                { typeof(BigInteger).FullName, CsToDb.New(KdbndpDbType.Numeric, "numeric", "numeric(78,0) NOT NULL", false, false, 0) },{ typeof(BigInteger?).FullName, CsToDb.New(KdbndpDbType.Numeric, "numeric", "numeric(78,0)", false, true, null) },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                { typeof(KdbndpPoint).FullName, CsToDb.New(KdbndpDbType.Point, "point", "point NOT NULL", false, false, new KdbndpPoint(0, 0)) },{ typeof(KdbndpPoint?).FullName, CsToDb.New(KdbndpDbType.Point, "point", "point", false, true, null) },
 | 
				
			||||||
 | 
					                { typeof(KdbndpLine).FullName, CsToDb.New(KdbndpDbType.Line, "line", "line NOT NULL", false, false, new KdbndpLine(0, 0, 1)) },{ typeof(KdbndpLine?).FullName, CsToDb.New(KdbndpDbType.Line, "line", "line", false, true, null) },
 | 
				
			||||||
 | 
					                { typeof(KdbndpLSeg).FullName, CsToDb.New(KdbndpDbType.LSeg, "lseg", "lseg NOT NULL", false, false, new KdbndpLSeg(0, 0, 0, 0)) },{ typeof(KdbndpLSeg?).FullName, CsToDb.New(KdbndpDbType.LSeg, "lseg", "lseg", false, true, null) },
 | 
				
			||||||
 | 
					                { typeof(KdbndpBox).FullName, CsToDb.New(KdbndpDbType.Box, "box", "box NOT NULL", false, false, new KdbndpBox(0, 0, 0, 0)) },{ typeof(KdbndpBox?).FullName, CsToDb.New(KdbndpDbType.Box, "box", "box", false, true, null) },
 | 
				
			||||||
 | 
					                { typeof(KdbndpPath).FullName, CsToDb.New(KdbndpDbType.Path, "path", "path NOT NULL", false, false, new KdbndpPath(new KdbndpPoint(0, 0))) },{ typeof(KdbndpPath?).FullName, CsToDb.New(KdbndpDbType.Path, "path", "path", false, true, null) },
 | 
				
			||||||
 | 
					                { typeof(KdbndpPolygon).FullName, CsToDb.New(KdbndpDbType.Polygon, "polygon", "polygon NOT NULL", false, false, new KdbndpPolygon(new KdbndpPoint(0, 0), new KdbndpPoint(0, 0))) },{ typeof(KdbndpPolygon?).FullName, CsToDb.New(KdbndpDbType.Polygon, "polygon", "polygon", false, true, null) },
 | 
				
			||||||
 | 
					                { typeof(KdbndpCircle).FullName, CsToDb.New(KdbndpDbType.Circle, "circle", "circle NOT NULL", false, false, new KdbndpCircle(0, 0, 0)) },{ typeof(KdbndpCircle?).FullName, CsToDb.New(KdbndpDbType.Circle, "circle", "circle", false, true, null) },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                { typeof((IPAddress Address, int Subnet)).FullName, CsToDb.New(KdbndpDbType.Cidr, "cidr", "cidr NOT NULL", false, false, (IPAddress.Any, 0)) },{ typeof((IPAddress Address, int Subnet)?).FullName, CsToDb.New(KdbndpDbType.Cidr, "cidr", "cidr", false, true, null) },
 | 
				
			||||||
 | 
					                { typeof(IPAddress).FullName, CsToDb.New(KdbndpDbType.Inet, "inet", "inet", false, null, IPAddress.Any) },
 | 
				
			||||||
 | 
					                { typeof(PhysicalAddress).FullName, CsToDb.New(KdbndpDbType.MacAddr, "macaddr", "macaddr", false, null, PhysicalAddress.None) },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                { typeof(JToken).FullName, CsToDb.New(KdbndpDbType.Jsonb, "jsonb", "jsonb", false, null, JToken.Parse("{}")) },
 | 
				
			||||||
 | 
					                { typeof(JObject).FullName, CsToDb.New(KdbndpDbType.Jsonb, "jsonb", "jsonb", false, null, JObject.Parse("{}")) },
 | 
				
			||||||
 | 
					                { typeof(JArray).FullName, CsToDb.New(KdbndpDbType.Jsonb, "jsonb", "jsonb", false, null, JArray.Parse("[]")) },
 | 
				
			||||||
                { typeof(Guid).FullName, CsToDb.New(KdbndpDbType.Uuid, "uuid", "uuid NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(KdbndpDbType.Uuid, "uuid", "uuid", false, true, null) },
 | 
					                { typeof(Guid).FullName, CsToDb.New(KdbndpDbType.Uuid, "uuid", "uuid NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(KdbndpDbType.Uuid, "uuid", "uuid", false, true, null) },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                { typeof(KdbndpRange<int>).FullName, CsToDb.New(KdbndpDbType.Range | KdbndpDbType.Integer, "int4range", "int4range NOT NULL", false, false, KdbndpRange<int>.Empty) },{ typeof(KdbndpRange<int>?).FullName, CsToDb.New(KdbndpDbType.Range | KdbndpDbType.Integer, "int4range", "int4range", false, true, null) },
 | 
				
			||||||
 | 
					                { typeof(KdbndpRange<long>).FullName, CsToDb.New(KdbndpDbType.Range | KdbndpDbType.Bigint, "int8range", "int8range NOT NULL", false, false, KdbndpRange<long>.Empty) },{ typeof(KdbndpRange<long>?).FullName, CsToDb.New(KdbndpDbType.Range | KdbndpDbType.Bigint, "int8range", "int8range", false, true, null) },
 | 
				
			||||||
 | 
					                { typeof(KdbndpRange<decimal>).FullName, CsToDb.New(KdbndpDbType.Range | KdbndpDbType.Numeric, "numrange", "numrange NOT NULL", false, false, KdbndpRange<decimal>.Empty) },{ typeof(KdbndpRange<decimal>?).FullName, CsToDb.New(KdbndpDbType.Range | KdbndpDbType.Numeric, "numrange", "numrange", false, true, null) },
 | 
				
			||||||
 | 
					                { typeof(KdbndpRange<DateTime>).FullName, CsToDb.New(KdbndpDbType.Range | KdbndpDbType.Timestamp, "tsrange", "tsrange NOT NULL", false, false, KdbndpRange<DateTime>.Empty) },{ typeof(KdbndpRange<DateTime>?).FullName, CsToDb.New(KdbndpDbType.Range | KdbndpDbType.Timestamp, "tsrange", "tsrange", false, true, null) },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                { typeof(Dictionary<string, string>).FullName, CsToDb.New(KdbndpDbType.Hstore, "hstore", "hstore", false, null, new Dictionary<string, string>()) },
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public override DbInfoResult GetDbInfo(Type type)
 | 
					        public override DbInfoResult GetDbInfo(Type type)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new DbInfoResult((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue);
 | 
					            var isarray = type.FullName != "System.Byte[]" && type.IsArray;
 | 
				
			||||||
 | 
					            var elementType = isarray ? type.GetElementType() : type;
 | 
				
			||||||
 | 
					            var info = GetDbInfoNoneArray(elementType);
 | 
				
			||||||
 | 
					            if (info == null) return null;
 | 
				
			||||||
 | 
					            if (isarray == false) return new DbInfoResult((int)info.type, info.dbtype, info.dbtypeFull, info.isnullable, info.defaultValue);
 | 
				
			||||||
 | 
					            var dbtypefull = Regex.Replace(info.dbtypeFull, $@"{info.dbtype}(\s*\([^\)]+\))?", "$0[]").Replace(" NOT NULL", "");
 | 
				
			||||||
 | 
					            return new DbInfoResult((int)(info.type | KdbndpDbType.Array), $"{info.dbtype}[]", dbtypefull, null, Array.CreateInstance(elementType, 0));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        CsToDb<KdbndpDbType> GetDbInfoNoneArray(Type type)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return trydc;
 | 
				
			||||||
            if (type.IsArray) return null;
 | 
					            if (type.IsArray) return null;
 | 
				
			||||||
            var enumType = type.IsEnum ? type : null;
 | 
					            var enumType = type.IsEnum ? type : null;
 | 
				
			||||||
            if (enumType == null && type.IsNullableType())
 | 
					            if (enumType == null && type.IsNullableType() && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First();
 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                var genericTypes = type.GetGenericArguments();
 | 
					 | 
				
			||||||
                if (genericTypes.Length == 1 && genericTypes.First().IsEnum) enumType = genericTypes.First();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            if (enumType != null)
 | 
					            if (enumType != null)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ?
 | 
					                var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ?
 | 
				
			||||||
@@ -65,7 +107,7 @@ namespace FreeSql.KingbaseES
 | 
				
			|||||||
                            _dicCsToDb.Add(type.FullName, newItem);
 | 
					                            _dicCsToDb.Add(type.FullName, newItem);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                return new DbInfoResult((int)newItem.type, newItem.dbtype, newItem.dbtypeFull, newItem.isnullable, newItem.defaultValue);
 | 
					                return newItem;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            return null;
 | 
					            return null;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,12 +2,16 @@
 | 
				
			|||||||
using FreeSql.Internal;
 | 
					using FreeSql.Internal;
 | 
				
			||||||
using FreeSql.Internal.Model;
 | 
					using FreeSql.Internal.Model;
 | 
				
			||||||
using KdbndpTypes;
 | 
					using KdbndpTypes;
 | 
				
			||||||
 | 
					using Newtonsoft.Json.Linq;
 | 
				
			||||||
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;
 | 
				
			||||||
using System.Data.Common;
 | 
					using System.Data.Common;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Net;
 | 
				
			||||||
 | 
					using System.Net.NetworkInformation;
 | 
				
			||||||
using System.Text;
 | 
					using System.Text;
 | 
				
			||||||
using System.Text.RegularExpressions;
 | 
					using System.Text.RegularExpressions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -25,75 +29,175 @@ namespace FreeSql.KingbaseES
 | 
				
			|||||||
            _commonExpression = commonExpression;
 | 
					            _commonExpression = commonExpression;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public int GetDbType(DbColumnInfo column) => (int)GetSqlDbType(column);
 | 
					        public int GetDbType(DbColumnInfo column) => (int)GetKdbndpDbType(column);
 | 
				
			||||||
        KdbndpDbType GetSqlDbType(DbColumnInfo column)
 | 
					        KdbndpDbType GetKdbndpDbType(DbColumnInfo column)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var dbtype = column.DbTypeText;
 | 
					            var dbtype = column.DbTypeText;
 | 
				
			||||||
            var isarray = dbtype?.EndsWith("[]") == true;
 | 
					            var isarray = dbtype?.EndsWith("[]") == true;
 | 
				
			||||||
            if (isarray) dbtype = dbtype.Remove(dbtype.Length - 2);
 | 
					            if (isarray) dbtype = dbtype.Remove(dbtype.Length - 2);
 | 
				
			||||||
            var ret = KdbndpDbType.Unknown;
 | 
					            KdbndpDbType ret = KdbndpDbType.Unknown;
 | 
				
			||||||
            switch (dbtype?.ToLower().TrimStart('_'))
 | 
					            switch (dbtype?.ToLower().TrimStart('_'))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                case "tinyint": ret = KdbndpDbType.Smallint; break;
 | 
					                case "smallint":
 | 
				
			||||||
                case "int2": ret = KdbndpDbType.Smallint; break;
 | 
					                case "int2": ret = KdbndpDbType.Smallint; break;
 | 
				
			||||||
 | 
					                case "integer":
 | 
				
			||||||
                case "int4": ret = KdbndpDbType.Integer; break;
 | 
					                case "int4": ret = KdbndpDbType.Integer; break;
 | 
				
			||||||
 | 
					                case "bigint":
 | 
				
			||||||
                case "int8": ret = KdbndpDbType.Bigint; break;
 | 
					                case "int8": ret = KdbndpDbType.Bigint; break;
 | 
				
			||||||
                case "numeric": ret = KdbndpDbType.Numeric; break;
 | 
					                case "numeric": ret = KdbndpDbType.Numeric; break;
 | 
				
			||||||
 | 
					                case "real":
 | 
				
			||||||
                case "float4": ret = KdbndpDbType.Real; break;
 | 
					                case "float4": ret = KdbndpDbType.Real; break;
 | 
				
			||||||
 | 
					                case "double precision":
 | 
				
			||||||
                case "float8": ret = KdbndpDbType.Double; break;
 | 
					                case "float8": ret = KdbndpDbType.Double; break;
 | 
				
			||||||
                case "money": ret = KdbndpDbType.Money; break;
 | 
					                case "money": ret = KdbndpDbType.Money; break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case "char": ret = column.MaxLength == 36 ? KdbndpDbType.Uuid : KdbndpDbType.Char; break;
 | 
					 | 
				
			||||||
                case "bpchar": ret = KdbndpDbType.Char; break;
 | 
					                case "bpchar": ret = KdbndpDbType.Char; break;
 | 
				
			||||||
 | 
					                case "character varying":
 | 
				
			||||||
                case "varchar": ret = KdbndpDbType.Varchar; break;
 | 
					                case "varchar": ret = KdbndpDbType.Varchar; break;
 | 
				
			||||||
                case "text": ret = KdbndpDbType.Text; break;
 | 
					                case "text": ret = KdbndpDbType.Text; break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case "datetime": ret = KdbndpDbType.Timestamp; break;
 | 
					 | 
				
			||||||
                case "timestamp": ret = KdbndpDbType.Timestamp; break;
 | 
					                case "timestamp": ret = KdbndpDbType.Timestamp; break;
 | 
				
			||||||
                case "timestamptz": ret = KdbndpDbType.Timestamp; break;
 | 
					                case "timestamptz": ret = KdbndpDbType.TimestampTz; break;
 | 
				
			||||||
                case "date": ret = KdbndpDbType.Date; break;
 | 
					                case "date": ret = KdbndpDbType.Date; break;
 | 
				
			||||||
                case "time": ret = KdbndpDbType.Time; break;
 | 
					                case "time": ret = KdbndpDbType.Time; break;
 | 
				
			||||||
                case "timetz": ret = KdbndpDbType.Time; break;
 | 
					                case "timetz": ret = KdbndpDbType.TimeTz; break;
 | 
				
			||||||
                case "interval": ret = KdbndpDbType.Time; break;
 | 
					                case "interval": ret = KdbndpDbType.Interval; break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case "bool": ret = KdbndpDbType.Boolean; break;
 | 
					                case "bool": ret = KdbndpDbType.Boolean; break;
 | 
				
			||||||
                case "blob": ret = KdbndpDbType.Bytea; break;
 | 
					 | 
				
			||||||
                case "bytea": ret = KdbndpDbType.Bytea; break;
 | 
					                case "bytea": ret = KdbndpDbType.Bytea; break;
 | 
				
			||||||
                case "bit": ret = KdbndpDbType.Bit; break;
 | 
					                case "bit": ret = KdbndpDbType.Bit; break;
 | 
				
			||||||
                case "varbit": ret = KdbndpDbType.Varbit; break;
 | 
					                case "varbit": ret = KdbndpDbType.Varbit; break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                case "point": ret = KdbndpDbType.Point; break;
 | 
				
			||||||
 | 
					                case "line": ret = KdbndpDbType.Line; break;
 | 
				
			||||||
 | 
					                case "lseg": ret = KdbndpDbType.LSeg; break;
 | 
				
			||||||
 | 
					                case "box": ret = KdbndpDbType.Box; break;
 | 
				
			||||||
 | 
					                case "path": ret = KdbndpDbType.Path; break;
 | 
				
			||||||
 | 
					                case "polygon": ret = KdbndpDbType.Polygon; break;
 | 
				
			||||||
 | 
					                case "circle": ret = KdbndpDbType.Circle; break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                case "cidr": ret = KdbndpDbType.Cidr; break;
 | 
				
			||||||
 | 
					                case "inet": ret = KdbndpDbType.Inet; break;
 | 
				
			||||||
 | 
					                case "macaddr": ret = KdbndpDbType.MacAddr; break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                case "json": ret = KdbndpDbType.Json; break;
 | 
				
			||||||
 | 
					                case "jsonb": ret = KdbndpDbType.Jsonb; break;
 | 
				
			||||||
                case "uuid": ret = KdbndpDbType.Uuid; break;
 | 
					                case "uuid": ret = KdbndpDbType.Uuid; break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                case "int4range": ret = KdbndpDbType.Range | KdbndpDbType.Integer; break;
 | 
				
			||||||
 | 
					                case "int8range": ret = KdbndpDbType.Range | KdbndpDbType.Bigint; break;
 | 
				
			||||||
 | 
					                case "numrange": ret = KdbndpDbType.Range | KdbndpDbType.Numeric; break;
 | 
				
			||||||
 | 
					                case "tsrange": ret = KdbndpDbType.Range | KdbndpDbType.Timestamp; break;
 | 
				
			||||||
 | 
					                case "tstzrange": ret = KdbndpDbType.Range | KdbndpDbType.TimestampTz; break;
 | 
				
			||||||
 | 
					                case "daterange": ret = KdbndpDbType.Range | KdbndpDbType.Date; break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                case "hstore": ret = KdbndpDbType.Hstore; break;
 | 
				
			||||||
 | 
					                case "geometry": ret = KdbndpDbType.Geometry; break;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            return ret;
 | 
					            return isarray ? (ret | KdbndpDbType.Array) : ret;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        static ConcurrentDictionary<int, DbToCs> _dicDbToCs = new ConcurrentDictionary<int, DbToCs>();
 | 
					        static readonly Dictionary<int, (string csConvert, string csParse, string csStringify, string csType, Type csTypeInfo, Type csNullableTypeInfo, string csTypeValue, string dataReaderMethod)> _dicDbToCs = new Dictionary<int, (string csConvert, string csParse, string csStringify, string csType, Type csTypeInfo, Type csNullableTypeInfo, string csTypeValue, string dataReaderMethod)>() {
 | 
				
			||||||
        static KingbaseESDbFirst()
 | 
					                { (int)KdbndpDbType.Smallint, ("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") },
 | 
				
			||||||
        {
 | 
					                { (int)KdbndpDbType.Integer, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") },
 | 
				
			||||||
            var defaultDbToCs = new Dictionary<int, DbToCs>() {
 | 
					                { (int)KdbndpDbType.Bigint, ("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") },
 | 
				
			||||||
                { (int)KdbndpDbType.Smallint, new DbToCs("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(int), typeof(int?), "{0}.Value", "GetInt16") },
 | 
					                { (int)KdbndpDbType.Numeric, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") },
 | 
				
			||||||
                { (int)KdbndpDbType.Integer, new DbToCs("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(long), typeof(long?), "{0}.Value", "GetInt32") },
 | 
					                { (int)KdbndpDbType.Real, ("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") },
 | 
				
			||||||
                { (int)KdbndpDbType.Bigint, new DbToCs("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") },
 | 
					                { (int)KdbndpDbType.Double, ("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") },
 | 
				
			||||||
                { (int)KdbndpDbType.Real, new DbToCs("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") },
 | 
					                { (int)KdbndpDbType.Money, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") },
 | 
				
			||||||
                { (int)KdbndpDbType.Double, new DbToCs("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") },
 | 
					 | 
				
			||||||
                { (int)KdbndpDbType.Numeric, new DbToCs("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") },
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                { (int)KdbndpDbType.Char, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") },
 | 
					                { (int)KdbndpDbType.Char, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") },
 | 
				
			||||||
                { (int)KdbndpDbType.Varchar, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") },
 | 
					                { (int)KdbndpDbType.Varchar, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") },
 | 
				
			||||||
                { (int)KdbndpDbType.Text, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") },
 | 
					                { (int)KdbndpDbType.Text, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                { (int)KdbndpDbType.Timestamp, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") },
 | 
					                { (int)KdbndpDbType.Timestamp,  ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") },
 | 
				
			||||||
                { (int)KdbndpDbType.Date, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") },
 | 
					                { (int)KdbndpDbType.TimestampTz,  ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") },
 | 
				
			||||||
                { (int)KdbndpDbType.Time, new DbToCs("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") },
 | 
					                { (int)KdbndpDbType.Date,  ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") },
 | 
				
			||||||
 | 
					                { (int)KdbndpDbType.Time, ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)KdbndpDbType.TimeTz, ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)KdbndpDbType.Interval, ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                { (int)KdbndpDbType.Boolean, new DbToCs("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") },
 | 
					                { (int)KdbndpDbType.Boolean, ("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") },
 | 
				
			||||||
                { (int)KdbndpDbType.Bytea, new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") },
 | 
					                { (int)KdbndpDbType.Bytea, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)KdbndpDbType.Bit, ("(BitArray)", "{0}.ToBitArray()", "{0}.To1010()", "BitArray", typeof(BitArray), typeof(BitArray), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)KdbndpDbType.Varbit, ("(BitArray)", "{0}.ToBitArray()", "{0}.To1010()", "BitArray", typeof(BitArray), typeof(BitArray), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                { (int)KdbndpDbType.Uuid, new DbToCs("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid", typeof(Guid), typeof(Guid?), "{0}", "GetString") },
 | 
					                { (int)KdbndpDbType.Point, ("(KdbndpPoint?)", "KdbndpPoint.Parse({0})", "{0}.ToString()", "KdbndpPoint", typeof(KdbndpPoint), typeof(KdbndpPoint?), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)KdbndpDbType.Line, ("(KdbndpLine?)", "KdbndpLine.Parse({0})", "{0}.ToString()", "KdbndpLine", typeof(KdbndpLine), typeof(KdbndpLine?), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)KdbndpDbType.LSeg, ("(KdbndpLSeg?)", "KdbndpLSeg.Parse({0})", "{0}.ToString()", "KdbndpLSeg", typeof(KdbndpLSeg), typeof(KdbndpLSeg?), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)KdbndpDbType.Box, ("(KdbndpBox?)", "KdbndpBox.Parse({0})", "{0}.ToString()", "KdbndpBox", typeof(KdbndpBox), typeof(KdbndpBox?), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)KdbndpDbType.Path, ("(KdbndpPath?)", "KdbndpPath.Parse({0})", "{0}.ToString()", "KdbndpPath", typeof(KdbndpPath), typeof(KdbndpPath?), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)KdbndpDbType.Polygon, ("(KdbndpPolygon?)", "KdbndpPolygon.Parse({0})", "{0}.ToString()", "KdbndpPolygon", typeof(KdbndpPolygon), typeof(KdbndpPolygon?), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)KdbndpDbType.Circle, ("(KdbndpCircle?)", "KdbndpCircle.Parse({0})", "{0}.ToString()", "KdbndpCircle", typeof(KdbndpCircle), typeof(KdbndpCircle?), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                { (int)KdbndpDbType.Cidr, ("((IPAddress, int)?)", "(IPAddress, int)({0})", "{0}.ToString()", "(IPAddress, int)", typeof((IPAddress, int)), typeof((IPAddress, int)?), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)KdbndpDbType.Inet, ("(IPAddress)", "IPAddress.Parse({0})", "{0}.ToString()", "IPAddress", typeof(IPAddress), typeof(IPAddress), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)KdbndpDbType.MacAddr, ("(PhysicalAddress?)", "PhysicalAddress.Parse({0})", "{0}.ToString()", "PhysicalAddress", typeof(PhysicalAddress), typeof(PhysicalAddress), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                { (int)KdbndpDbType.Json, ("(JToken)", "JToken.Parse({0})", "{0}.ToString()", "JToken", typeof(JToken), typeof(JToken), "{0}", "GetString") },
 | 
				
			||||||
 | 
					                { (int)KdbndpDbType.Jsonb, ("(JToken)", "JToken.Parse({0})", "{0}.ToString()", "JToken", typeof(JToken), typeof(JToken), "{0}", "GetString") },
 | 
				
			||||||
 | 
					                { (int)KdbndpDbType.Uuid, ("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid", typeof(Guid), typeof(Guid?), "{0}", "GetString") },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Range | KdbndpDbType.Integer), ("(KdbndpRange<int>?)", "{0}.ToKdbndpRange<int>()", "{0}.ToString()", "KdbndpRange<int>", typeof(KdbndpRange<int>), typeof(KdbndpRange<int>?), "{0}", "GetString") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Range | KdbndpDbType.Bigint), ("(KdbndpRange<long>?)", "{0}.ToKdbndpRange<long>()", "{0}.ToString()", "KdbndpRange<long>", typeof(KdbndpRange<long>), typeof(KdbndpRange<long>?), "{0}", "GetString") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Range | KdbndpDbType.Numeric), ("(KdbndpRange<decimal>?)", "{0}.ToKdbndpRange<decimal>()", "{0}.ToString()", "KdbndpRange<decimal>", typeof(KdbndpRange<decimal>), typeof(KdbndpRange<decimal>?), "{0}", "GetString") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Range | KdbndpDbType.Timestamp), ("(KdbndpRange<DateTime>?)", "{0}.ToKdbndpRange<DateTime>()", "{0}.ToString()", "KdbndpRange<DateTime>", typeof(KdbndpRange<DateTime>), typeof(KdbndpRange<DateTime>?), "{0}", "GetString") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Range | KdbndpDbType.TimestampTz), ("(KdbndpRange<DateTime>?)", "{0}.ToKdbndpRange<DateTime>()", "{0}.ToString()", "KdbndpRange<DateTime>", typeof(KdbndpRange<DateTime>), typeof(KdbndpRange<DateTime>?), "{0}", "GetString") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Range | KdbndpDbType.Date), ("(KdbndpRange<DateTime>?)", "{0}.ToKdbndpRange<DateTime>()", "{0}.ToString()", "KdbndpRange<DateTime>", typeof(KdbndpRange<DateTime>), typeof(KdbndpRange<DateTime>?), "{0}", "GetString") },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                { (int)KdbndpDbType.Hstore, ("(Dictionary<string, string>)", "JsonConvert.DeserializeObject<Dictionary<string, string>>({0})", "JsonConvert.SerializeObject({0})", "Dictionary<string, string>", typeof(Dictionary<string, string>), typeof(Dictionary<string, string>), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									/*** array ***/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									{ (int)(KdbndpDbType.Smallint | KdbndpDbType.Array), ("(short[])", "JsonConvert.DeserializeObject<short[]>({0})", "JsonConvert.SerializeObject({0})", "short[]", typeof(short[]), typeof(short[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Integer | KdbndpDbType.Array), ("(int[])", "JsonConvert.DeserializeObject<int[]>({0})", "JsonConvert.SerializeObject({0})", "int[]", typeof(int[]), typeof(int[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Bigint | KdbndpDbType.Array), ("(long[])", "JsonConvert.DeserializeObject<long[]>({0})", "JsonConvert.SerializeObject({0})", "long[]", typeof(long[]), typeof(long[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Numeric | KdbndpDbType.Array), ("(decimal[])", "JsonConvert.DeserializeObject<decimal[]>({0})", "JsonConvert.SerializeObject({0})", "decimal[]", typeof(decimal[]), typeof(decimal[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Real | KdbndpDbType.Array), ("(float[])", "JsonConvert.DeserializeObject<float[]>({0})", "JsonConvert.SerializeObject({0})", "float[]", typeof(float[]), typeof(float[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Double | KdbndpDbType.Array), ("(double[])", "JsonConvert.DeserializeObject<double[]>({0})", "JsonConvert.SerializeObject({0})", "double[]", typeof(double[]), typeof(double[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Money | KdbndpDbType.Array), ("(decimal[])", "JsonConvert.DeserializeObject<decimal[]>({0})", "JsonConvert.SerializeObject({0})", "decimal[]", typeof(decimal[]), typeof(decimal[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Char | KdbndpDbType.Array), ("(string[])", "JsonConvert.DeserializeObject<string[]>({0})", "JsonConvert.SerializeObject({0})", "string[]", typeof(string[]), typeof(string[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Varchar | KdbndpDbType.Array), ("(string[])", "JsonConvert.DeserializeObject<string[]>({0})", "JsonConvert.SerializeObject({0})", "string[]", typeof(string[]), typeof(string[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Text | KdbndpDbType.Array), ("(string[])", "JsonConvert.DeserializeObject<string[]>({0})", "JsonConvert.SerializeObject({0})", "string[]", typeof(string[]), typeof(string[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Timestamp | KdbndpDbType.Array), ("(DateTime[])", "JsonConvert.DeserializeObject<DateTime[]>({0})", "JsonConvert.SerializeObject({0})", "DateTime[]", typeof(DateTime[]), typeof(DateTime[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.TimestampTz | KdbndpDbType.Array), ("(DateTime[])", "JsonConvert.DeserializeObject<DateTime[]>({0})", "JsonConvert.SerializeObject({0})", "DateTime[]", typeof(DateTime[]), typeof(DateTime[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Date | KdbndpDbType.Array), ("(DateTime[])", "JsonConvert.DeserializeObject<DateTime[]>({0})", "JsonConvert.SerializeObject({0})", "DateTime[]", typeof(DateTime[]), typeof(DateTime[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Time | KdbndpDbType.Array), ("(TimeSpan[])", "JsonConvert.DeserializeObject<TimeSpan[]>({0})", "JsonConvert.SerializeObject({0})", "TimeSpan[]", typeof(TimeSpan[]), typeof(TimeSpan[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.TimeTz | KdbndpDbType.Array), ("(TimeSpan[])", "JsonConvert.DeserializeObject<TimeSpan[]>({0})", "JsonConvert.SerializeObject({0})", "TimeSpan[]", typeof(TimeSpan[]), typeof(TimeSpan[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Interval | KdbndpDbType.Array), ("(TimeSpan[])", "JsonConvert.DeserializeObject<TimeSpan[]>({0})", "JsonConvert.SerializeObject({0})", "TimeSpan[]", typeof(TimeSpan[]), typeof(TimeSpan[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Boolean | KdbndpDbType.Array), ("(bool[])", "JsonConvert.DeserializeObject<bool[]>({0})", "JsonConvert.SerializeObject({0})", "bool[]", typeof(bool[]), typeof(bool[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Bytea | KdbndpDbType.Array), ("(byte[][])", "JsonConvert.DeserializeObject<byte[][]>({0})", "JsonConvert.SerializeObject({0})", "byte[][]", typeof(byte[][]), typeof(byte[][]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Bit | KdbndpDbType.Array), ("(BitArray[])", "JsonConvert.DeserializeObject<BitArray[]>({0})", "JsonConvert.SerializeObject({0})", "BitArray[]", typeof(BitArray[]), typeof(BitArray[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Varbit | KdbndpDbType.Array), ("(BitArray[])", "JsonConvert.DeserializeObject<BitArray[]>({0})", "JsonConvert.SerializeObject({0})", "BitArray[]", typeof(BitArray[]), typeof(BitArray[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Point | KdbndpDbType.Array), ("(KdbndpPoint[])", "JsonConvert.DeserializeObject<KdbndpPoint[]>({0})", "JsonConvert.SerializeObject({0})", "KdbndpPoint[]", typeof(KdbndpPoint[]), typeof(KdbndpPoint[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Line | KdbndpDbType.Array), ("(KdbndpLine[])", "JsonConvert.DeserializeObject<BKdbndpLineitArray[]>({0})", "JsonConvert.SerializeObject({0})", "KdbndpLine[]", typeof(KdbndpLine[]), typeof(KdbndpLine[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.LSeg | KdbndpDbType.Array), ("(KdbndpLSeg[])", "JsonConvert.DeserializeObject<KdbndpLSeg[]>({0})", "JsonConvert.SerializeObject({0})", "KdbndpLSeg[]", typeof(KdbndpLSeg[]), typeof(KdbndpLSeg[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Box | KdbndpDbType.Array), ("(KdbndpBox[])", "JsonConvert.DeserializeObject<KdbndpBox[]>({0})", "JsonConvert.SerializeObject({0})", "KdbndpBox[]", typeof(KdbndpBox[]), typeof(KdbndpBox[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Path | KdbndpDbType.Array), ("(KdbndpPath[])", "JsonConvert.DeserializeObject<KdbndpPath[]>({0})", "JsonConvert.SerializeObject({0})", "KdbndpPath[]", typeof(KdbndpPath[]), typeof(KdbndpPath[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Polygon | KdbndpDbType.Array), ("(KdbndpPolygon[])", "JsonConvert.DeserializeObject<KdbndpPolygon[]>({0})", "JsonConvert.SerializeObject({0})", "KdbndpPolygon[]", typeof(KdbndpPolygon[]), typeof(KdbndpPolygon[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Circle | KdbndpDbType.Array), ("(KdbndpCircle[])", "JsonConvert.DeserializeObject<KdbndpCircle[]>({0})", "JsonConvert.SerializeObject({0})", "KdbndpCircle[]", typeof(KdbndpCircle[]), typeof(KdbndpCircle[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Cidr | KdbndpDbType.Array), ("((IPAddress, int)[])", "JsonConvert.DeserializeObject<(IPAddress, int)[]>({0})", "JsonConvert.SerializeObject({0})", "(IPAddress, int)[]", typeof((IPAddress, int)[]), typeof((IPAddress, int)[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Inet | KdbndpDbType.Array), ("(IPAddress[])", "JsonConvert.DeserializeObject<IPAddress[]>({0})", "JsonConvert.SerializeObject({0})", "IPAddress[]", typeof(IPAddress[]), typeof(IPAddress[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.MacAddr | KdbndpDbType.Array), ("(PhysicalAddress[])", "JsonConvert.DeserializeObject<PhysicalAddress[]>({0})", "JsonConvert.SerializeObject({0})", "PhysicalAddress[]", typeof(PhysicalAddress[]), typeof(PhysicalAddress[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Json | KdbndpDbType.Array), ("(JToken[])", "JsonConvert.DeserializeObject<JToken[]>({0})", "JsonConvert.SerializeObject({0})", "JToken[]", typeof(JToken[]), typeof(JToken[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Jsonb | KdbndpDbType.Array), ("(JToken[])", "JsonConvert.DeserializeObject<JToken[]>({0})", "JsonConvert.SerializeObject({0})", "JToken[]", typeof(JToken[]), typeof(JToken[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Uuid | KdbndpDbType.Array), ("(Guid[])", "JsonConvert.DeserializeObject<Guid[]>({0})", "JsonConvert.SerializeObject({0})", "Guid[]", typeof(Guid[]), typeof(Guid[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Range | KdbndpDbType.Integer | KdbndpDbType.Array), ("(KdbndpRange<int>[])", "JsonConvert.DeserializeObject<KdbndpRange<int>[]>({0})", "JsonConvert.SerializeObject({0})", "KdbndpRange<int>[]", typeof(KdbndpRange<int>[]), typeof(KdbndpRange<int>[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Range | KdbndpDbType.Bigint | KdbndpDbType.Array), ("(KdbndpRange<long>[])", "JsonConvert.DeserializeObject<KdbndpRange<long>[]>({0})", "JsonConvert.SerializeObject({0})", "KdbndpRange<long>[]", typeof(KdbndpRange<long>[]), typeof(KdbndpRange<long>[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Range | KdbndpDbType.Numeric | KdbndpDbType.Array), ("(KdbndpRange<decimal>[])", "JsonConvert.DeserializeObject<KdbndpRange<decimal>[]>({0})", "JsonConvert.SerializeObject({0})", "KdbndpRange<decimal>[]", typeof(KdbndpRange<decimal>[]), typeof(KdbndpRange<decimal>[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Range | KdbndpDbType.Timestamp | KdbndpDbType.Array), ("(KdbndpRange<DateTime>[])", "JsonConvert.DeserializeObject<KdbndpRange<DateTime>[]>({0})", "JsonConvert.SerializeObject({0})", "KdbndpRange<DateTime>[]", typeof(KdbndpRange<DateTime>[]), typeof(KdbndpRange<DateTime>[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Range | KdbndpDbType.TimestampTz | KdbndpDbType.Array), ("(KdbndpRange<DateTime>[])", "JsonConvert.DeserializeObject<KdbndpRange<DateTime>[]>({0})", "JsonConvert.SerializeObject({0})", "KdbndpRange<DateTime>[]", typeof(KdbndpRange<DateTime>[]), typeof(KdbndpRange<DateTime>[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Range | KdbndpDbType.Date | KdbndpDbType.Array), ("(KdbndpRange<DateTime>[])", "JsonConvert.DeserializeObject<KdbndpRange<DateTime>[]>({0})", "JsonConvert.SerializeObject({0})", "KdbndpRange<DateTime>[]", typeof(KdbndpRange<DateTime>[]), typeof(KdbndpRange<DateTime>[]), "{0}", "GetValue") },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                { (int)(KdbndpDbType.Hstore | KdbndpDbType.Array), ("(Dictionary<string, string>[])", "JsonConvert.DeserializeObject<Dictionary<string, string>[]>({0})", "JsonConvert.SerializeObject({0})", "Dictionary<string, string>[]", typeof(Dictionary<string, string>[]), typeof(Dictionary<string, string>[]), "{0}", "GetValue") },
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
            foreach (var kv in defaultDbToCs)
 | 
					 | 
				
			||||||
                _dicDbToCs.TryAdd(kv.Key, kv.Value);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null;
 | 
					        public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null;
 | 
				
			||||||
        public string GetCsParse(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csParse : null;
 | 
					        public string GetCsParse(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csParse : null;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,5 @@
 | 
				
			|||||||
using FreeSql.Internal;
 | 
					using FreeSql.Internal;
 | 
				
			||||||
 | 
					using Newtonsoft.Json.Linq;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections;
 | 
					using System.Collections;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
@@ -98,10 +99,10 @@ namespace FreeSql.KingbaseES
 | 
				
			|||||||
                                    var enumStr = ExpressionLambdaToSql(callExp.Object, tsc);
 | 
					                                    var enumStr = ExpressionLambdaToSql(callExp.Object, tsc);
 | 
				
			||||||
                                    tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType);
 | 
					                                    tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType);
 | 
				
			||||||
                                    return enumStr;
 | 
					                                    return enumStr;
 | 
				
			||||||
								}
 | 
					                                }
 | 
				
			||||||
								var value = ExpressionGetValue(callExp.Object, out var success);
 | 
					                                var value = ExpressionGetValue(callExp.Object, out var success);
 | 
				
			||||||
								if (success) return formatSql(value, typeof(string), null, null);
 | 
					                                if (success) return formatSql(value, typeof(string), null, null);
 | 
				
			||||||
								return callExp.Arguments.Count == 0 ? $"({getExp(callExp.Object)})::text" : null;
 | 
					                                return callExp.Arguments.Count == 0 ? $"({getExp(callExp.Object)})::text" : null;
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                            return null;
 | 
					                            return null;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
@@ -131,6 +132,36 @@ namespace FreeSql.KingbaseES
 | 
				
			|||||||
                    if (objType != null || objType.IsArrayOrList())
 | 
					                    if (objType != null || objType.IsArrayOrList())
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        string left = null;
 | 
					                        string left = null;
 | 
				
			||||||
 | 
					                        switch (objType.FullName)
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            case "Newtonsoft.Json.Linq.JToken":
 | 
				
			||||||
 | 
					                            case "Newtonsoft.Json.Linq.JObject":
 | 
				
			||||||
 | 
					                            case "Newtonsoft.Json.Linq.JArray":
 | 
				
			||||||
 | 
					                                left = objExp == null ? null : getExp(objExp);
 | 
				
			||||||
 | 
					                                switch (callExp.Method.Name)
 | 
				
			||||||
 | 
					                                {
 | 
				
			||||||
 | 
					                                    case "get_Item": return $"{left}->{getExp(callExp.Arguments[argIndex])}";
 | 
				
			||||||
 | 
					                                    case "Any": return $"(jsonb_array_length(coalesce({left},'[]')) > 0)";
 | 
				
			||||||
 | 
					                                    case "Contains":
 | 
				
			||||||
 | 
					                                        var json = getExp(callExp.Arguments[argIndex]);
 | 
				
			||||||
 | 
					                                        if (objType == typeof(JArray))
 | 
				
			||||||
 | 
					                                            return $"(coalesce({left},'[]') ? ({json})::text)";
 | 
				
			||||||
 | 
					                                        if (json.StartsWith("'") && json.EndsWith("'"))
 | 
				
			||||||
 | 
					                                            return $"(coalesce({left},'{{}}') @> {_common.FormatSql("{0}", JToken.Parse(json.Trim('\'')))})";
 | 
				
			||||||
 | 
					                                        return $"(coalesce({left},'{{}}') @> ({json})::jsonb)";
 | 
				
			||||||
 | 
					                                    case "ContainsKey": return $"(coalesce({left},'{{}}') ? {getExp(callExp.Arguments[argIndex])})";
 | 
				
			||||||
 | 
					                                    case "Concat":
 | 
				
			||||||
 | 
					                                        var right2 = getExp(callExp.Arguments[argIndex]);
 | 
				
			||||||
 | 
					                                        return $"(coalesce({left},'{{}}') || {right2})";
 | 
				
			||||||
 | 
					                                    case "LongCount":
 | 
				
			||||||
 | 
					                                    case "Count": return $"jsonb_array_length(coalesce({left},'[]'))";
 | 
				
			||||||
 | 
					                                    case "Parse":
 | 
				
			||||||
 | 
					                                        var json2 = getExp(callExp.Arguments[argIndex]);
 | 
				
			||||||
 | 
					                                        if (json2.StartsWith("'") && json2.EndsWith("'")) return _common.FormatSql("{0}", JToken.Parse(json2.Trim('\'')));
 | 
				
			||||||
 | 
					                                        return $"({json2})::jsonb";
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					                                break;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
                        if (objType == typeof(Dictionary<string, string>))
 | 
					                        if (objType == typeof(Dictionary<string, string>))
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            left = objExp == null ? null : getExp(objExp);
 | 
					                            left = objExp == null ? null : getExp(objExp);
 | 
				
			||||||
@@ -165,14 +196,14 @@ namespace FreeSql.KingbaseES
 | 
				
			|||||||
                                tsc.isNotSetMapColumnTmp = false;
 | 
					                                tsc.isNotSetMapColumnTmp = false;
 | 
				
			||||||
                                tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType);
 | 
					                                tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType);
 | 
				
			||||||
                                if (oldDbParams != null) tsc.SetDbParamsReturnOld(oldDbParams);
 | 
					                                if (oldDbParams != null) tsc.SetDbParamsReturnOld(oldDbParams);
 | 
				
			||||||
								//判断 in 或 array @> array
 | 
					                                //判断 in 或 array @> array
 | 
				
			||||||
								if (left.StartsWith("array[") && left.EndsWith("]"))
 | 
					                                if (left.StartsWith("array[") && left.EndsWith("]"))
 | 
				
			||||||
									return $"({args1}) in ({left.Substring(6, left.Length - 7)})";
 | 
					                                    return $"({args1}) in ({left.Substring(6, left.Length - 7)})";
 | 
				
			||||||
								if (left.StartsWith("(") && left.EndsWith(")")) //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格
 | 
					                                if (left.StartsWith("(") && left.EndsWith(")")) //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格
 | 
				
			||||||
									return $"(({args1}) in {left.Replace(",   \r\n    \r\n", $") \r\n OR ({args1}) in (")})";
 | 
					                                    return $"(({args1}) in {left.Replace(",   \r\n    \r\n", $") \r\n OR ({args1}) in (")})";
 | 
				
			||||||
								if (args1.StartsWith("(") && args1.EndsWith(")")) args1 = $"array[{args1.TrimStart('(').TrimEnd(')')}]";
 | 
					                                if (args1.StartsWith("(") && args1.EndsWith(")")) args1 = $"array[{args1.TrimStart('(').TrimEnd(')')}]";
 | 
				
			||||||
								else args1 = $"array[{args1}]";
 | 
					                                else args1 = $"array[{args1}]";
 | 
				
			||||||
								if (objExp != null)
 | 
					                                if (objExp != null)
 | 
				
			||||||
                                {
 | 
					                                {
 | 
				
			||||||
                                    var dbinfo = _common._orm.CodeFirst.GetDbInfo(objExp.Type);
 | 
					                                    var dbinfo = _common._orm.CodeFirst.GetDbInfo(objExp.Type);
 | 
				
			||||||
                                    if (dbinfo != null) args1 = $"{args1}::{dbinfo.dbtype}";
 | 
					                                    if (dbinfo != null) args1 = $"{args1}::{dbinfo.dbtype}";
 | 
				
			||||||
@@ -210,6 +241,28 @@ namespace FreeSql.KingbaseES
 | 
				
			|||||||
                                case "Count": return $"case when {left} is null then 0 else array_length({left},1) end";
 | 
					                                case "Count": return $"case when {left} is null then 0 else array_length({left},1) end";
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
 | 
					                        switch (memParentExp.FullName)
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            case "Newtonsoft.Json.Linq.JToken":
 | 
				
			||||||
 | 
					                            case "Newtonsoft.Json.Linq.JObject":
 | 
				
			||||||
 | 
					                            case "Newtonsoft.Json.Linq.JArray":
 | 
				
			||||||
 | 
					                                var left = getExp(memExp.Expression);
 | 
				
			||||||
 | 
					                                switch (memExp.Member.Name)
 | 
				
			||||||
 | 
					                                {
 | 
				
			||||||
 | 
					                                    case "Count": return $"jsonb_array_length(coalesce({left},'[]'))";
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					                                break;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        if (memParentExp == typeof(Dictionary<string, string>))
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            var left = getExp(memExp.Expression);
 | 
				
			||||||
 | 
					                            switch (memExp.Member.Name)
 | 
				
			||||||
 | 
					                            {
 | 
				
			||||||
 | 
					                                case "Count": return $"case when {left} is null then 0 else array_length(akeys({left}),1) end";
 | 
				
			||||||
 | 
					                                case "Keys": return $"akeys({left})";
 | 
				
			||||||
 | 
					                                case "Values": return $"avals({left})";
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
                case ExpressionType.NewArrayInit:
 | 
					                case ExpressionType.NewArrayInit:
 | 
				
			||||||
@@ -316,7 +369,7 @@ namespace FreeSql.KingbaseES
 | 
				
			|||||||
                            return _common.StringConcat(concatNewArrExp.Expressions.Select(a => getExp(a)).ToArray(), null);
 | 
					                            return _common.StringConcat(concatNewArrExp.Expressions.Select(a => getExp(a)).ToArray(), null);
 | 
				
			||||||
                        return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null);
 | 
					                        return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null);
 | 
				
			||||||
                    case "Format":
 | 
					                    case "Format":
 | 
				
			||||||
                        if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception(CoreStrings.Not_Implemented_Expression_ParameterUseConstant(exp,exp.Arguments[0]));
 | 
					                        if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception(CoreStrings.Not_Implemented_Expression_ParameterUseConstant(exp, exp.Arguments[0]));
 | 
				
			||||||
                        var expArgsHack = exp.Arguments.Count == 2 && exp.Arguments[1].NodeType == ExpressionType.NewArrayInit ?
 | 
					                        var expArgsHack = exp.Arguments.Count == 2 && exp.Arguments[1].NodeType == ExpressionType.NewArrayInit ?
 | 
				
			||||||
                            (exp.Arguments[1] as NewArrayExpression).Expressions : exp.Arguments.Where((a, z) => z > 0);
 | 
					                            (exp.Arguments[1] as NewArrayExpression).Expressions : exp.Arguments.Where((a, z) => z > 0);
 | 
				
			||||||
                        //3个 {} 时,Arguments 解析出来是分开的
 | 
					                        //3个 {} 时,Arguments 解析出来是分开的
 | 
				
			||||||
@@ -395,6 +448,8 @@ namespace FreeSql.KingbaseES
 | 
				
			|||||||
                            if (exp.Method.Name == "TrimStart") return $"ltrim({left})";
 | 
					                            if (exp.Method.Name == "TrimStart") return $"ltrim({left})";
 | 
				
			||||||
                            if (exp.Method.Name == "TrimEnd") return $"rtrim({left})";
 | 
					                            if (exp.Method.Name == "TrimEnd") return $"rtrim({left})";
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
 | 
					                        var trimArg1 = "";
 | 
				
			||||||
 | 
					                        var trimArg2 = "";
 | 
				
			||||||
                        foreach (var argsTrim02 in exp.Arguments)
 | 
					                        foreach (var argsTrim02 in exp.Arguments)
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            var argsTrim01s = new[] { argsTrim02 };
 | 
					                            var argsTrim01s = new[] { argsTrim02 };
 | 
				
			||||||
@@ -405,11 +460,14 @@ namespace FreeSql.KingbaseES
 | 
				
			|||||||
                            }
 | 
					                            }
 | 
				
			||||||
                            foreach (var argsTrim01 in argsTrim01s)
 | 
					                            foreach (var argsTrim01 in argsTrim01s)
 | 
				
			||||||
                            {
 | 
					                            {
 | 
				
			||||||
                                if (exp.Method.Name == "Trim") left = $"trim(both {getExp(argsTrim01)} from {left})";
 | 
					                                var trimChr = getExp(argsTrim01).Trim('\'');
 | 
				
			||||||
                                if (exp.Method.Name == "TrimStart") left = $"ltrim({left},{getExp(argsTrim01)})";
 | 
					                                if (trimChr.Length == 1) trimArg1 += trimChr;
 | 
				
			||||||
                                if (exp.Method.Name == "TrimEnd") left = $"rtrim({left},{getExp(argsTrim01)})";
 | 
					                                else trimArg2 += $" || ({trimChr})";
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
 | 
					                        if (exp.Method.Name == "Trim") left = $"trim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})";
 | 
				
			||||||
 | 
					                        if (exp.Method.Name == "TrimStart") left = $"ltrim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})";
 | 
				
			||||||
 | 
					                        if (exp.Method.Name == "TrimEnd") left = $"rtrim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})";
 | 
				
			||||||
                        return left;
 | 
					                        return left;
 | 
				
			||||||
                    case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})";
 | 
					                    case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})";
 | 
				
			||||||
                    case "CompareTo": return $"case when {left} = {getExp(exp.Arguments[0])} then 0 when {left} > {getExp(exp.Arguments[0])} then 1 else -1 end";
 | 
					                    case "CompareTo": return $"case when {left} = {getExp(exp.Arguments[0])} then 0 when {left} > {getExp(exp.Arguments[0])} then 1 else -1 end";
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,7 @@ using FreeSql.Internal.CommonProvider;
 | 
				
			|||||||
using FreeSql.Internal.Model;
 | 
					using FreeSql.Internal.Model;
 | 
				
			||||||
using Kdbndp;
 | 
					using Kdbndp;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Data;
 | 
					using System.Data;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
@@ -20,6 +21,13 @@ public static partial class FreeSqlKingbaseESGlobalExtensions
 | 
				
			|||||||
    public static string FormatKingbaseES(this string that, params object[] args) => _kingbaseesAdo.Addslashes(that, args);
 | 
					    public static string FormatKingbaseES(this string that, params object[] args) => _kingbaseesAdo.Addslashes(that, args);
 | 
				
			||||||
    static FreeSql.KingbaseES.KingbaseESAdo _kingbaseesAdo = new FreeSql.KingbaseES.KingbaseESAdo();
 | 
					    static FreeSql.KingbaseES.KingbaseESAdo _kingbaseesAdo = new FreeSql.KingbaseES.KingbaseESAdo();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    internal static string To1010(this BitArray ba)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        char[] ret = new char[ba.Length];
 | 
				
			||||||
 | 
					        for (int a = 0; a < ba.Length; a++) ret[a] = ba[a] ? '1' : '0';
 | 
				
			||||||
 | 
					        return new string(ret);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #region ExecuteKdbCopy
 | 
					    #region ExecuteKdbCopy
 | 
				
			||||||
    /// <summary>
 | 
					    /// <summary>
 | 
				
			||||||
    /// 批量插入或更新(操作的字段数量超过 2000 时收益大)<para></para>
 | 
					    /// 批量插入或更新(操作的字段数量超过 2000 时收益大)<para></para>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,17 @@
 | 
				
			|||||||
using FreeSql.Internal.CommonProvider;
 | 
					using FreeSql.Internal;
 | 
				
			||||||
 | 
					using FreeSql.Internal.CommonProvider;
 | 
				
			||||||
 | 
					using KdbndpTypes;
 | 
				
			||||||
 | 
					using Newtonsoft.Json;
 | 
				
			||||||
 | 
					using Newtonsoft.Json.Linq;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Data.Common;
 | 
					using System.Data.Common;
 | 
				
			||||||
 | 
					using System.Linq.Expressions;
 | 
				
			||||||
 | 
					using System.Net;
 | 
				
			||||||
 | 
					using System.Net.NetworkInformation;
 | 
				
			||||||
 | 
					using System.Numerics;
 | 
				
			||||||
 | 
					using System.Reflection;
 | 
				
			||||||
using System.Threading;
 | 
					using System.Threading;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace FreeSql.KingbaseES
 | 
					namespace FreeSql.KingbaseES
 | 
				
			||||||
@@ -8,6 +19,73 @@ namespace FreeSql.KingbaseES
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public class KingbaseESProvider<TMark> : BaseDbProvider, IFreeSql<TMark>
 | 
					    public class KingbaseESProvider<TMark> : BaseDbProvider, IFreeSql<TMark>
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        static int _firstInit = 1;
 | 
				
			||||||
 | 
					        static void InitInternal()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (Interlocked.Exchange(ref _firstInit, 0) == 1) //不能放在 static ctor .NetFramework 可能报初始化类型错误
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Utils.dicExecuteArrayRowReadClassOrTuple[typeof(BigInteger)] = true;
 | 
				
			||||||
 | 
					                Utils.dicExecuteArrayRowReadClassOrTuple[typeof(BitArray)] = true;
 | 
				
			||||||
 | 
					                Utils.dicExecuteArrayRowReadClassOrTuple[typeof(KdbndpPoint)] = true;
 | 
				
			||||||
 | 
					                Utils.dicExecuteArrayRowReadClassOrTuple[typeof(KdbndpLine)] = true;
 | 
				
			||||||
 | 
					                Utils.dicExecuteArrayRowReadClassOrTuple[typeof(KdbndpLSeg)] = true;
 | 
				
			||||||
 | 
					                Utils.dicExecuteArrayRowReadClassOrTuple[typeof(KdbndpBox)] = true;
 | 
				
			||||||
 | 
					                Utils.dicExecuteArrayRowReadClassOrTuple[typeof(KdbndpPath)] = true;
 | 
				
			||||||
 | 
					                Utils.dicExecuteArrayRowReadClassOrTuple[typeof(KdbndpPolygon)] = true;
 | 
				
			||||||
 | 
					                Utils.dicExecuteArrayRowReadClassOrTuple[typeof(KdbndpCircle)] = true;
 | 
				
			||||||
 | 
					                Utils.dicExecuteArrayRowReadClassOrTuple[typeof((IPAddress Address, int Subnet))] = true;
 | 
				
			||||||
 | 
					                Utils.dicExecuteArrayRowReadClassOrTuple[typeof(IPAddress)] = true;
 | 
				
			||||||
 | 
					                Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PhysicalAddress)] = true;
 | 
				
			||||||
 | 
					                Utils.dicExecuteArrayRowReadClassOrTuple[typeof(KdbndpRange<int>)] = true;
 | 
				
			||||||
 | 
					                Utils.dicExecuteArrayRowReadClassOrTuple[typeof(KdbndpRange<long>)] = true;
 | 
				
			||||||
 | 
					                Utils.dicExecuteArrayRowReadClassOrTuple[typeof(KdbndpRange<decimal>)] = true;
 | 
				
			||||||
 | 
					                Utils.dicExecuteArrayRowReadClassOrTuple[typeof(KdbndpRange<DateTime>)] = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                Utils.dicExecuteArrayRowReadClassOrTuple[typeof(Dictionary<string, string>)] = true;
 | 
				
			||||||
 | 
					                Utils.dicExecuteArrayRowReadClassOrTuple[typeof(JToken)] = true;
 | 
				
			||||||
 | 
					                Utils.dicExecuteArrayRowReadClassOrTuple[typeof(JObject)] = true;
 | 
				
			||||||
 | 
					                Utils.dicExecuteArrayRowReadClassOrTuple[typeof(JArray)] = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var MethodJTokenFromObject = typeof(JToken).GetMethod("FromObject", new[] { typeof(object) });
 | 
				
			||||||
 | 
					                var MethodJObjectFromObject = typeof(JObject).GetMethod("FromObject", new[] { typeof(object) });
 | 
				
			||||||
 | 
					                var MethodJArrayFromObject = typeof(JArray).GetMethod("FromObject", new[] { typeof(object) });
 | 
				
			||||||
 | 
					                var MethodJTokenParse = typeof(JToken).GetMethod("Parse", new[] { typeof(string) });
 | 
				
			||||||
 | 
					                var MethodJObjectParse = typeof(JObject).GetMethod("Parse", new[] { typeof(string) });
 | 
				
			||||||
 | 
					                var MethodJArrayParse = typeof(JArray).GetMethod("Parse", new[] { typeof(string) });
 | 
				
			||||||
 | 
					                var MethodJsonConvertDeserializeObject = typeof(JsonConvert).GetMethod("DeserializeObject", new[] { typeof(string), typeof(Type) });
 | 
				
			||||||
 | 
					                var MethodToString = typeof(Utils).GetMethod("ToStringConcat", BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(object) }, null);
 | 
				
			||||||
 | 
					                Utils.GetDataReaderValueBlockExpressionSwitchTypeFullName.Add((LabelTarget returnTarget, Expression valueExp, Type type) =>
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    switch (type.FullName)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        case "Newtonsoft.Json.Linq.JToken":
 | 
				
			||||||
 | 
					                            return Expression.IfThenElse(
 | 
				
			||||||
 | 
					                                Expression.TypeIs(valueExp, typeof(string)),
 | 
				
			||||||
 | 
					                                Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJTokenParse, Expression.Convert(valueExp, typeof(string))), typeof(JToken))),
 | 
				
			||||||
 | 
					                                Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJTokenFromObject, valueExp), typeof(JToken))));
 | 
				
			||||||
 | 
					                        case "Newtonsoft.Json.Linq.JObject":
 | 
				
			||||||
 | 
					                            return Expression.IfThenElse(
 | 
				
			||||||
 | 
					                                Expression.TypeIs(valueExp, typeof(string)),
 | 
				
			||||||
 | 
					                                Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJObjectParse, Expression.Convert(valueExp, typeof(string))), typeof(JObject))),
 | 
				
			||||||
 | 
					                                Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJObjectFromObject, valueExp), typeof(JObject))));
 | 
				
			||||||
 | 
					                        case "Newtonsoft.Json.Linq.JArray":
 | 
				
			||||||
 | 
					                            return Expression.IfThenElse(
 | 
				
			||||||
 | 
					                                Expression.TypeIs(valueExp, typeof(string)),
 | 
				
			||||||
 | 
					                                Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJArrayParse, Expression.Convert(valueExp, typeof(string))), typeof(JArray))),
 | 
				
			||||||
 | 
					                                Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJArrayFromObject, valueExp), typeof(JArray))));
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    if (typeof(IList).IsAssignableFrom(type))
 | 
				
			||||||
 | 
					                        return Expression.IfThenElse(
 | 
				
			||||||
 | 
					                            Expression.TypeIs(valueExp, typeof(string)),
 | 
				
			||||||
 | 
					                            Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJsonConvertDeserializeObject, Expression.Convert(valueExp, typeof(string)), Expression.Constant(type, typeof(Type))), type)),
 | 
				
			||||||
 | 
					                            Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJsonConvertDeserializeObject, Expression.Convert(Expression.Call(MethodToString, valueExp), typeof(string)), Expression.Constant(type, typeof(Type))), type)));
 | 
				
			||||||
 | 
					                    return null;
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                Select0Provider._dicMethodDataReaderGetValue[typeof(Guid)] = typeof(DbDataReader).GetMethod("GetGuid", new Type[] { typeof(int) });
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public override ISelect<T1> CreateSelectProvider<T1>(object dywhere) => new KingbaseESSelect<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere);
 | 
					        public override ISelect<T1> CreateSelectProvider<T1>(object dywhere) => new KingbaseESSelect<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere);
 | 
				
			||||||
        public override IInsert<T1> CreateInsertProvider<T1>() => new KingbaseESInsert<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression);
 | 
					        public override IInsert<T1> CreateInsertProvider<T1>() => new KingbaseESInsert<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression);
 | 
				
			||||||
        public override IUpdate<T1> CreateUpdateProvider<T1>(object dywhere) => new KingbaseESUpdate<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere);
 | 
					        public override IUpdate<T1> CreateUpdateProvider<T1>(object dywhere) => new KingbaseESUpdate<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere);
 | 
				
			||||||
@@ -16,6 +94,7 @@ namespace FreeSql.KingbaseES
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        public KingbaseESProvider(string masterConnectionString, string[] slaveConnectionString, Func<DbConnection> connectionFactory = null)
 | 
					        public KingbaseESProvider(string masterConnectionString, string[] slaveConnectionString, Func<DbConnection> connectionFactory = null)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            InitInternal();
 | 
				
			||||||
            this.InternalCommonUtils = new KingbaseESUtils(this);
 | 
					            this.InternalCommonUtils = new KingbaseESUtils(this);
 | 
				
			||||||
            this.InternalCommonExpression = new KingbaseESExpression(this.InternalCommonUtils);
 | 
					            this.InternalCommonExpression = new KingbaseESExpression(this.InternalCommonUtils);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,11 +2,15 @@
 | 
				
			|||||||
using FreeSql.Internal.Model;
 | 
					using FreeSql.Internal.Model;
 | 
				
			||||||
using Kdbndp;
 | 
					using Kdbndp;
 | 
				
			||||||
using KdbndpTypes;
 | 
					using KdbndpTypes;
 | 
				
			||||||
 | 
					using Newtonsoft.Json.Linq;
 | 
				
			||||||
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.Globalization;
 | 
					using System.Globalization;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Net;
 | 
				
			||||||
 | 
					using System.Numerics;
 | 
				
			||||||
using System.Text;
 | 
					using System.Text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace FreeSql.KingbaseES
 | 
					namespace FreeSql.KingbaseES
 | 
				
			||||||
@@ -31,32 +35,55 @@ namespace FreeSql.KingbaseES
 | 
				
			|||||||
            return ret;
 | 
					            return ret;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        static Dictionary<string, Func<object, object>> dicGetParamterValue = new Dictionary<string, Func<object, object>> {
 | 
					        static Dictionary<string, Func<object, object>> dicGetParamterValue = new Dictionary<string, Func<object, object>> {
 | 
				
			||||||
 | 
					            { typeof(JToken).FullName, a => string.Concat(a) }, { typeof(JToken[]).FullName, a => getParamterArrayValue(typeof(string), a, null) },
 | 
				
			||||||
 | 
					            { typeof(JObject).FullName, a => string.Concat(a) }, { typeof(JObject[]).FullName, a => getParamterArrayValue(typeof(string), a, null) },
 | 
				
			||||||
 | 
					            { typeof(JArray).FullName, a => string.Concat(a) }, { typeof(JArray[]).FullName, a => getParamterArrayValue(typeof(string), a, null) },
 | 
				
			||||||
            { typeof(uint).FullName, a => long.Parse(string.Concat(a)) }, { typeof(uint[]).FullName, a => getParamterArrayValue(typeof(long), a, 0) }, { typeof(uint?[]).FullName, a => getParamterArrayValue(typeof(long?), a, null) },
 | 
					            { typeof(uint).FullName, a => long.Parse(string.Concat(a)) }, { typeof(uint[]).FullName, a => getParamterArrayValue(typeof(long), a, 0) }, { typeof(uint?[]).FullName, a => getParamterArrayValue(typeof(long?), a, null) },
 | 
				
			||||||
            { typeof(ulong).FullName, a => decimal.Parse(string.Concat(a)) }, { typeof(ulong[]).FullName, a => getParamterArrayValue(typeof(decimal), a, 0) }, { typeof(ulong?[]).FullName, a => getParamterArrayValue(typeof(decimal?), a, null) },
 | 
					            { typeof(ulong).FullName, a => decimal.Parse(string.Concat(a)) }, { typeof(ulong[]).FullName, a => getParamterArrayValue(typeof(decimal), a, 0) }, { typeof(ulong?[]).FullName, a => getParamterArrayValue(typeof(decimal?), a, null) },
 | 
				
			||||||
            { typeof(ushort).FullName, a => int.Parse(string.Concat(a)) }, { typeof(ushort[]).FullName, a => getParamterArrayValue(typeof(int), a, 0) }, { typeof(ushort?[]).FullName, a => getParamterArrayValue(typeof(int?), a, null) },
 | 
					            { typeof(ushort).FullName, a => int.Parse(string.Concat(a)) }, { typeof(ushort[]).FullName, a => getParamterArrayValue(typeof(int), a, 0) }, { typeof(ushort?[]).FullName, a => getParamterArrayValue(typeof(int?), a, null) },
 | 
				
			||||||
            { typeof(byte).FullName, a => short.Parse(string.Concat(a)) }, { typeof(byte[]).FullName, a => getParamterArrayValue(typeof(short), a, 0) }, { typeof(byte?[]).FullName, a => getParamterArrayValue(typeof(short?), a, null) },
 | 
					            { typeof(byte).FullName, a => short.Parse(string.Concat(a)) }, { typeof(byte[]).FullName, a => getParamterArrayValue(typeof(short), a, 0) }, { typeof(byte?[]).FullName, a => getParamterArrayValue(typeof(short?), a, null) },
 | 
				
			||||||
            { typeof(sbyte).FullName, a => short.Parse(string.Concat(a)) }, { typeof(sbyte[]).FullName, a => getParamterArrayValue(typeof(short), a, 0) }, { typeof(sbyte?[]).FullName, a => getParamterArrayValue(typeof(short?), a, null) },
 | 
					            { typeof(sbyte).FullName, a => short.Parse(string.Concat(a)) }, { typeof(sbyte[]).FullName, a => getParamterArrayValue(typeof(short), a, 0) }, { typeof(sbyte?[]).FullName, a => getParamterArrayValue(typeof(short?), a, null) },
 | 
				
			||||||
            { typeof(char).FullName, a => string.Concat(a).Replace('\0', ' ').ToCharArray().FirstOrDefault() },
 | 
					            { typeof(char).FullName, a => string.Concat(a).Replace('\0', ' ').ToCharArray().FirstOrDefault() },
 | 
				
			||||||
 | 
					            { typeof(BigInteger).FullName, a => BigInteger.Parse(string.Concat(a), System.Globalization.NumberStyles.Any) }, { typeof(BigInteger[]).FullName, a => getParamterArrayValue(typeof(BigInteger), a, 0) }, { typeof(BigInteger?[]).FullName, a => getParamterArrayValue(typeof(BigInteger?), a, null) },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            { typeof(KdbndpPath).FullName, a => {
 | 
				
			||||||
 | 
					                var path = (KdbndpPath)a;
 | 
				
			||||||
 | 
					                try { int count = path.Count; return path; } catch { return new KdbndpPath(new KdbndpPoint(0, 0)); }
 | 
				
			||||||
 | 
					            } },
 | 
				
			||||||
 | 
					            { typeof(KdbndpPath[]).FullName, a => getParamterArrayValue(typeof(KdbndpPath), a, new KdbndpPath(new KdbndpPoint(0, 0))) },
 | 
				
			||||||
 | 
					            { typeof(KdbndpPath?[]).FullName, a => getParamterArrayValue(typeof(KdbndpPath?), a, null) },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            { typeof(KdbndpPolygon).FullName, a =>  {
 | 
				
			||||||
 | 
					                var polygon = (KdbndpPolygon)a;
 | 
				
			||||||
 | 
					                try { int count = polygon.Count; return polygon; } catch { return new KdbndpPolygon(new KdbndpPoint(0, 0), new KdbndpPoint(0, 0)); }
 | 
				
			||||||
 | 
					            } },
 | 
				
			||||||
 | 
					            { typeof(KdbndpPolygon[]).FullName, a => getParamterArrayValue(typeof(KdbndpPolygon), a, new KdbndpPolygon(new KdbndpPoint(0, 0), new KdbndpPoint(0, 0))) },
 | 
				
			||||||
 | 
					            { typeof(KdbndpPolygon?[]).FullName, a => getParamterArrayValue(typeof(KdbndpPolygon?), a, null) },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            { typeof((IPAddress Address, int Subnet)).FullName, a => {
 | 
				
			||||||
 | 
					                var inet = ((IPAddress Address, int Subnet))a;
 | 
				
			||||||
 | 
					                if (inet.Address == null) return (IPAddress.Any, inet.Subnet);
 | 
				
			||||||
 | 
					                return inet;
 | 
				
			||||||
 | 
					            } },
 | 
				
			||||||
 | 
					            { typeof((IPAddress Address, int Subnet)[]).FullName, a => getParamterArrayValue(typeof((IPAddress Address, int Subnet)), a, (IPAddress.Any, 0)) },
 | 
				
			||||||
 | 
					            { typeof((IPAddress Address, int Subnet)?[]).FullName, a => getParamterArrayValue(typeof((IPAddress Address, int Subnet)?), a, null) },
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        static object getParamterValue(Type type, object value, int level = 0)
 | 
					        static object getParamterValue(Type type, object value, int level = 0)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (type.FullName == "System.Byte[]") return value;
 | 
					            if (type.FullName == "System.Byte[]") return value;
 | 
				
			||||||
 | 
					            if (type.FullName == "System.Char[]") return value;
 | 
				
			||||||
            if (type.IsArray && level == 0)
 | 
					            if (type.IsArray && level == 0)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var elementType = type.GetElementType();
 | 
					                var elementType = type.GetElementType();
 | 
				
			||||||
                Type enumType = null;
 | 
					                Type enumType = null;
 | 
				
			||||||
                if (elementType.IsEnum) enumType = elementType;
 | 
					                if (elementType.IsEnum) enumType = elementType;
 | 
				
			||||||
                else if (elementType.IsNullableType())
 | 
					                else if (elementType.IsNullableType() && elementType.GenericTypeArguments.First().IsEnum) enumType = elementType.GenericTypeArguments.First();
 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    var genericTypesFirst = elementType.GetGenericArguments().First();
 | 
					 | 
				
			||||||
                    if (genericTypesFirst.IsEnum) enumType = genericTypesFirst;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                if (enumType != null) return enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ?
 | 
					                if (enumType != null) return enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ?
 | 
				
			||||||
                    getParamterArrayValue(typeof(long), value, elementType.IsEnum ? null : enumType.CreateInstanceGetDefaultValue()) :
 | 
					                    getParamterArrayValue(typeof(long), value, elementType.IsEnum ? null : enumType.CreateInstanceGetDefaultValue()) :
 | 
				
			||||||
                    getParamterArrayValue(typeof(int), value, elementType.IsEnum ? null : enumType.CreateInstanceGetDefaultValue());
 | 
					                    getParamterArrayValue(typeof(int), value, elementType.IsEnum ? null : enumType.CreateInstanceGetDefaultValue());
 | 
				
			||||||
                return dicGetParamterValue.TryGetValue(type.FullName, out var trydicarr) ? trydicarr(value) : value;
 | 
					                return dicGetParamterValue.TryGetValue(type.FullName, out var trydicarr) ? trydicarr(value) : value;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if (type.IsNullableType()) type = type.GetGenericArguments().First();
 | 
					            if (type.IsNullableType()) type = type.GenericTypeArguments.First();
 | 
				
			||||||
            if (type.IsEnum) return (int)value;
 | 
					            if (type.IsEnum) return (int)value;
 | 
				
			||||||
            if (dicGetParamterValue.TryGetValue(type.FullName, out var trydic)) return trydic(value);
 | 
					            if (dicGetParamterValue.TryGetValue(type.FullName, out var trydic)) return trydic(value);
 | 
				
			||||||
            return value;
 | 
					            return value;
 | 
				
			||||||
@@ -72,6 +99,17 @@ namespace FreeSql.KingbaseES
 | 
				
			|||||||
            //} else {
 | 
					            //} else {
 | 
				
			||||||
            var tp = _orm.CodeFirst.GetDbInfo(type)?.type;
 | 
					            var tp = _orm.CodeFirst.GetDbInfo(type)?.type;
 | 
				
			||||||
            if (tp != null) ret.KdbndpDbType = (KdbndpDbType)tp.Value;
 | 
					            if (tp != null) ret.KdbndpDbType = (KdbndpDbType)tp.Value;
 | 
				
			||||||
 | 
					            if (col != null)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var dbtype = (KdbndpDbType)_orm.DbFirst.GetDbType(new DatabaseModel.DbColumnInfo { DbTypeText = col.DbTypeText });
 | 
				
			||||||
 | 
					                if (dbtype != KdbndpDbType.Unknown)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    ret.KdbndpDbType = dbtype;
 | 
				
			||||||
 | 
					                    //if (col.DbSize != 0) ret.Size = col.DbSize;
 | 
				
			||||||
 | 
					                    if (col.DbPrecision != 0) ret.Precision = col.DbPrecision;
 | 
				
			||||||
 | 
					                    if (col.DbScale != 0) ret.Scale = col.DbScale;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            //}
 | 
					            //}
 | 
				
			||||||
            _params?.Add(ret);
 | 
					            _params?.Add(ret);
 | 
				
			||||||
            return ret;
 | 
					            return ret;
 | 
				
			||||||
@@ -148,6 +186,20 @@ namespace FreeSql.KingbaseES
 | 
				
			|||||||
                if (dbinfo != null) sb.Append("::").Append(dbinfo.dbtype);
 | 
					                if (dbinfo != null) sb.Append("::").Append(dbinfo.dbtype);
 | 
				
			||||||
                return sb.ToString();
 | 
					                return sb.ToString();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            else if (type2 == typeof(BitArray))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return $"'{(value as BitArray).To1010()}'";
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else if (type2 == typeof(KdbndpLine) || type2 == typeof(KdbndpLine?))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                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))
 | 
					            else if (dicGetParamterValue.ContainsKey(type2.FullName))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                value = string.Concat(value);
 | 
					                value = string.Concat(value);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user