From d33109c3b10b29313070e944196894467e71666a Mon Sep 17 00:00:00 2001
From: 2881099 <2881099@qq.com>
Date: Wed, 14 Aug 2024 13:09:14 +0800
Subject: [PATCH] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20KingBaseES=20=E6=94=AF?=
=?UTF-8?q?=E6=8C=81=E6=95=B0=E7=BB=84=E7=AD=89=E7=B1=BB=E5=9E=8B=EF=BC=88?=
=?UTF-8?q?=E5=8F=82=E8=80=83=20PostgreSQL=EF=BC=89=EF=BC=9B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
FreeSql/FreeSql.xml | 1685 ++++++++---------
.../FreeSql.Provider.KingbaseES.csproj | 6 +-
.../KingbaseESAdo/KingbaseESAdo.cs | 41 +-
.../KingbaseESCodeFirst.cs | 56 +-
.../KingbaseESDbFirst.cs | 178 +-
.../KingbaseESExpression.cs | 90 +-
.../KingbaseESExtensions.cs | 8 +
.../KingbaseESProvider.cs | 81 +-
.../KingbaseESUtils.cs | 64 +-
9 files changed, 1280 insertions(+), 929 deletions(-)
diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml
index 44d4f9e4a..c021f7a98 100644
--- a/FreeSql/FreeSql.xml
+++ b/FreeSql/FreeSql.xml
@@ -1087,93 +1087,6 @@
-
-
- 动态创建实体类型
-
-
-
-
- 配置Class
-
- 类名
- 类标记的特性[Table(Name = "xxx")] [Index(xxxx)]
-
-
-
-
- 获取类型构建器,可作为要构建的Type来引用
-
-
-
-
- 配置属性
-
- 属性名称
- 属性类型
- 属性标记的特性-支持多个
-
-
-
-
- 配置属性
-
- 属性名称
- 属性类型
- 该属性是否重写父类属性
- 属性标记的特性-支持多个
-
-
-
-
- 配置属性
-
- 属性名称
- 属性类型
- 该属性是否重写父类属性
- 属性默认值
- 属性标记的特性-支持多个
-
-
-
-
- 配置父类
-
- 父类类型
-
-
-
-
- Override属性
-
-
-
-
-
- Emit动态创建出Class - Type
-
-
-
-
-
- Emit动态创建出Class - Type,不附带获取TableInfo
-
-
-
-
-
- 首字母小写
-
-
-
-
-
-
- 首字母大写
-
-
-
-
获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值时,返回 ""
@@ -2883,6 +2796,85 @@
lambda表达式
+
+
+ 按列排序,OrderBy(a => a.Time)
+
+
+
+
+
+
+
+ 实现 select .. from ( select ... from t ) a 这样的功能
+ 使用 AsTable 方法也可以达到效果
+ 示例:WithSql("select * from id=@id", new { id = 1 })
+ 提示:parms 参数还可以传 Dictionary<string, object>
+
+ SQL语句
+ 参数
+
+
+
+
+ 实现 select .. from ( select .. UNION ALL select .. ) a 这样的功能(基于内存数据)
+
+ 内存数据
+
+
+
+
+ 嵌套查询 select * from ( select ... from table ... ) a
+
+
+
+
+
+
+
+ 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com")
+
+ lambda表达式
+
+
+
+
+ 查询条件,Where(true, a => a.Id > 10),支导航对象查询,Where(true, a => a.Author.Email == "2881099@qq.com")
+
+ true 时生效
+ lambda表达式
+
+
+
+
+ 按列排序,OrderBy(a => a.Time)
+
+
+
+
+
+
+
+ 按列倒向排序,OrderByDescending(a => a.Time)
+
+ 列
+
+
+
+
+ 按聚合条件过滤,Having(a => a.Count() > 10)
+
+ lambda表达式
+
+
+
+
+ 按聚合条件过滤,HavingIf(true, a => a.Count() > 10)
+
+ true 时生效
+ lambda表达式
+
+
按列排序,OrderBy(a => a.Time)
@@ -3992,406 +3984,381 @@
- 标识符,可将 CurdBefore 与 CurdAfter 进行匹配
-
-
-
-
- 操作类型
-
+ 标识符,可将 CurdBefore 与 CurdAfter 进 表名,如:dbo.table1
+ 是否忽略大小写
+
-
+
- 实体类型
+ 获取数据库枚举类型int值
+
+
-
+
- 实体类型的元数据
+ 获取c#转换,(int)、(long)
+
+
-
+
- 执行的 SQL
+ 获取c#值
+
+
-
+
- 参数化命令
+ 获取c#类型,int、long
+
+
-
+
- 状态数据,可与 CurdAfter 共享
+ 获取c#类型对象
+
+
-
+
- 发生的错误
+ 获取ado.net读取方法, GetBoolean、GetInt64
+
+
-
+
- 执行SQL命令,返回的结果
+ 序列化
+
+
-
+
- 耗时(单位:Ticks)
+ 反序列化
+
+
-
+
- 耗时(单位:毫秒)
+ 获取数据库枚举类型,适用 PostgreSQL
+
+
-
+
- 标识符,可将 SyncStructureBeforeEventArgs 与 SyncStructureAfterEventArgs 进行匹配
+ 临时 LambdaExpression.Parameter
-
+
- 实体类型
+ 如果实体类有自增属性,分成两个 List,有值的Item1 merge,无值的Item2 insert
+
+
-
+
- 状态数据,可与 SyncStructureAfter 共享
+ AsType, Ctor, ClearData 三处地方需要重新加载
-
+
- 执行的 SQL
+ AsType, Ctor, ClearData 三处地方需要重新加载
-
+
- 发生的错误
+ 动态读取 DescriptionAttribute 注释文本
+
+
-
+
- 耗时(单位:Ticks)
+ 通过属性的注释文本,通过 xml 读取
+
+ Dict:key=属性名,value=注释
-
+
- 耗时(单位:毫秒)
+ 更新实体的元数据
-
+
- 类型
+ 执行更新的 SQL
-
+
- 属性列的元数据
+ 执行更新命令的参数
-
+
- 反射的属性信息
+ 执行更新命令影响的行
-
+
- 获取实体的属性值,也可以设置实体的属性新值
+ 更新的实体数量
-
+
- 实体对象
+ 更新的实体
-
+
- 中断实体对象审计
- false: 每个实体对象的属性都会审计(默认)
- true: 每个实体对象只审计一次
+ 映射优先级,默认: Attribute > FluentApi > Aop
-
+
- ADO.NET 数据流读取对象
+ 实体特性
+ [Table(Name = "tabname")]
+ [Column(Name = "table_id")]
-
+
- DataReader 对应的 Index 位置
+ 流式接口
+ fsql.CodeFirst.ConfigEntity(a => a.Name("tabname"))
+ fsql.CodeFirst.ConfigEntity(a => a.Property(b => b.Id).Name("table_id"))
-
+
- DataReader 对应的 PropertyInfo
+ AOP 特性 https://github.com/dotnetcore/FreeSql/wiki/AOP
+ fsql.Aop.ConfigEntity += (_, e) => e.ModifyResult.Name = "public.tabname";
+ fsql.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = "table_id";
-
+
- 获取 Index 对应的值,也可以设置拦截的新值
+ 不进行任何处理
-
+
- 标识符,可将 CommandBefore 与 CommandAfter 进行匹配
+ 将帕斯卡命名字符串转换为下划线分隔字符串
+
+ BigApple -> Big_Apple
-
+
- 状态数据,可与 CommandAfter 共享
+ 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写
+
+ BigApple -> BIG_APPLE
-
+
- 发生的错误
+ 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写
+
+ BigApple -> big_apple
-
+
- 执行SQL命令,返回的结果
+ 将字符串转换为大写
+
+ BigApple -> BIGAPPLE
-
+
- 耗时(单位:Ticks)
+ 将字符串转换为小写
+
+ BigApple -> bigapple
-
+
- 耗时(单位:毫秒)
+ 创建一个过滤器
+ 提示:在 Lambda 中判断登陆身份,请参考资料 AsyncLocal
+
+ 名字
+ 表达式
+ 条件在最前面
+
-
+
- 标识符,可将 TraceBeforeEventArgs 与 TraceAfterEventArgs 进行匹配
+ 创建一个动态过滤器,当 condition 返回值为 true 时才生效
+ 场景:当登陆身份是管理员,则过滤条件不生效
+ 提示:在 Lambda 中判断登陆身份,请参考资料 AsyncLocal
+
+ 名字
+ 委托,返回值为 true 时才生效
+ 表达式
+ 条件在最前面
+
-
+
- 状态数据,可与 TraceAfter 共享
-
-
-
-
- 备注
-
-
-
-
- 发生的错误
-
-
-
-
- 耗时(单位:Ticks)
-
-
-
-
- 耗时(单位:毫秒)
-
-
-
-
- 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改
-
-
-
-
- 转小写同步结构,适用 PostgreSQL
-
-
-
-
- 转大写同步结构,适用 Oracle/达梦/人大金仓
-
-
-
-
- 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。
- 本功能会影响 IFreeSql 首次访问的速度。
- 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除
-
-
-
-
- 不使用命令参数化执行,针对 Insert/Update
-
-
-
-
- 是否生成命令参数化执行,针对 lambda 表达式解析
- 注意:常量不会参数化,变量才会做参数化
- var id = 100;
- fsql.Select<T>().Where(a => a.id == id) 会参数化
- fsql.Select<T>().Where(a => a.id == 100) 不会参数化
+ 创建一个过滤器(实体类型 属于指定 TEntity 才会生效)
+ 提示:在 Lambda 中判断登陆身份,请参考资料 AsyncLocal
+
+ 名字
+ 表达式
+ 条件在最前面
+
-
+
- 延时加载导航属性对象,导航属性需要声明 virtual
+ 创建一个过滤器(实体类型 属于指定 TEntity 才会生效)
+ 场景:当登陆身份是管理员,则过滤条件不生效
+ 提示:在 Lambda 中判断登陆身份,请参考资料 AsyncLocal
+
+ 名字
+ 委托,返回值为 true 时才生效
+ 表达式
+ 条件在最前面
+
-
+
- 将实体类型与数据库对比,返回DDL语句
+ 使用指定 DbConnection 连接执行
-
+
-
+
- 将实体类型集合与数据库对比,返回DDL语句
+ 使用指定 DbTransaction 事务执行
- 实体类型
+
-
+
- 将实体类型与数据库对比,返回DDL语句(指定表名)
+ 增加参数化对象
- 实体类型
- 指定表名对比
+ 参数名
+ 参数值
+ 修改本次创建好的参数化对象,比如将 parameterName 参数修改为 Output 类型
-
+
- 同步实体类型到数据库
- 注意:生产环境中谨慎使用
+ 设置执行的命令类型,SQL文本、或存储过程
-
+
+
-
+
- 同步实体类型集合到数据库
- 注意:生产环境中谨慎使用
+ 设置命令执行超时(秒)
-
+
+
-
+
- 同步实体类型到数据库(指定表名)
- 注意:生产环境中谨慎使用
+ 分页信息
- 实体类型
- 指定表名对比
- 强制同步结构,无视缓存每次都同步
-
+
- 根据 System.Type 获取数据库信息
+ 第几页,从1开始
-
-
-
+
- FreeSql FluentApi 配置实体,方法名与特性相同
+ 每页多少
-
-
-
-
+
- FreeSql FluentApi 配置实体,方法名与特性相同
+ 查询的记录数量
-
-
-
-
+
- 获取 FreeSql FluentApi 配置实体的元数据
+ 当前操作的数据
-
- 未使用ConfigEntity配置时,返回null
-
+
- 获取实体类核心配置
+ 当前批次
-
-
-
+
- 获取所有数据库
+ 总批次数量
-
-
+
- 获取指定数据库的表信息,包括表、列详情、主键、唯一键、索引、外键、备注
+ 获取 obj.CsName 属性值 MapType 之后的数据库值
-
+
-
+
- 获取指定单表信息,包括列详情、主键、唯一键、索引、备注
+ 获取 obj.CsName 属性原始值(不经过 MapType)
- 表名,如:dbo.table1
- 是否忽略大小写
-
+
-
+
- 判断表是否存在
+ 设置 obj.CsName 属性值
- 表名,如:dbo.table1
- 是否忽略大小写
-
+
+
-
+
- 获取数据库枚举类型int值
+ 动态过滤条件
-
-
-
+
- 获取c#转换,(int)、(long)
+ 属性名:Name
+ 导航属性:Parent.Name
+ 多表:b.Name
-
-
-
+
- 获取c#值
+ 操作符
-
-
-
+
- 获取c#类型,int、long
+ 值
-
-
-
+
- 获取c#类型对象
+ Filters 下的逻辑运算符
-
-
-
+
- 获取ado.net读取方法, GetBoolean、GetInt64
+ 子过滤条件,它与当前的逻辑关系是 And
+ 注意:当前 Field 可以留空
-
-
-
+
- 序列化
-
-
-
+ like
@@ -4489,288 +4456,299 @@
流式接口
fsql.CodeFirst.ConfigEntity(a => a.Name("tabname"))
- fsql.CodeFirst.ConfigEntity(a => a.Property(b => b.Id).Name("table_id"))
+ fsql.CodeFirst.ConfigEn, string value) => value;
+ }
+ }
-
+
- AOP 特性 https://github.com/dotnetcore/FreeSql/wiki/AOP
- fsql.Aop.ConfigEntity += (_, e) => e.ModifyResult.Name = "public.tabname";
- fsql.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = "table_id";
+ 授权 DynamicFilter 支持 Custom 自定义解析
-
+
- 不进行任何处理
+ 是否放弃继续读取
-
+
- 将帕斯卡命名字符串转换为下划线分隔字符串
-
- BigApple -> Big_Apple
+ 中间表,多对多
-
+
- 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写
-
- BigApple -> BIG_APPLE
+ PostgreSQL 数组类型专属功能
+ 方式一:select * from Role where Id in (RoleIds)
+ class User {
+ ____public int[] RoleIds { get; set; }
+ ____[Navigate(nameof(RoleIds))]
+ ____public List<Role> Roles { get; set; }
+ }
+ 方式二:select * from User where RoleIds @> Id
+ class Role {
+ ____public int Id { get; set; }
+ ____[Navigate(nameof(User.RoleIds))]
+ ____public List<User> Users { get; set; }
+ }
-
+
- 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写
-
- BigApple -> big_apple
+ 是否可用
-
+
- 将字符串转换为大写
-
- BigApple -> BIGAPPLE
+ 不可用错误
-
+
- 将字符串转换为小写
-
- BigApple -> bigapple
+ 不可用时间
-
+
- 创建一个过滤器
- 提示:在 Lambda 中判断登陆身份,请参考资料 AsyncLocal
+ 将对象池设置为不可用,后续 Get/GetAsync 均会报错,同时启动后台定时检查服务恢复可用
-
- 名字
- 表达式
- 条件在最前面
-
+
+
+ 由【可用】变成【不可用】时返回true,否则返回false
-
+
- 创建一个动态过滤器,当 condition 返回值为 true 时才生效
- 场景:当登陆身份是管理员,则过滤条件不生效
- 提示:在 Lambda 中判断登陆身份,请参考资料 AsyncLocal
+ 统计对象池中的对象
-
- 名字
- 委托,返回值为 true 时才生效
- 表达式
- 条件在最前面
-
-
+
- 创建一个过滤器(实体类型 属于指定 TEntity 才会生效)
- 提示:在 Lambda 中判断登陆身份,请参考资料 AsyncLocal
+ 统计对象池中的对象(完整)
-
- 名字
- 表达式
- 条件在最前面
-
-
+
- 创建一个过滤器(实体类型 属于指定 TEntity 才会生效)
- 场景:当登陆身份是管理员,则过滤条件不生效
- 提示:在 Lambda 中判断登陆身份,请参考资料 AsyncLocal
+ 获取资源
-
- 名字
- 委托,返回值为 true 时才生效
- 表达式
- 条件在最前面
+ 超时
-
+
- 使用指定 DbConnection 连接执行
+ 使用完毕后,归还资源
-
-
+ 对象
+ 是否重新创建
-
+
- 使用指定 DbTransaction 事务执行
+ 名称
-
-
-
+
- 增加参数化对象
+ 池容量
- 参数名
- 参数值
- 修改本次创建好的参数化对象,比如将 parameterName 参数修改为 Output 类型
-
-
+
- 设置执行的命令类型,SQL文本、或存储过程
+ 默认获取超时设置
-
-
-
+
- 设置命令执行超时(秒)
+ 空闲时间,获取时若超出,则重新创建
-
-
-
+
- 分页信息
+ 异步获取排队队列大小,小于等于0不生效
-
+
- 第几页,从1开始
+ 获取超时后,是否抛出异常
-
+
- 每页多少
+ 监听 AppDomain.CurrentDomain.ProcessExit/Console.CancelKeyPress 事件自动释放
-
+
- 查询的记录数量
+ 后台定时检查可用性间隔秒数
-
+
- 当前操作的数据
+ 权重
-
+
- 当前批次
+ 对象池的对象被创建时
+ 返回被创建的对象
-
+
- 总批次数量
+ 销毁对象
+ 资源对象
-
+
- 获取 obj.CsName 属性值 MapType 之后的数据库值
+ 从对象池获取对象超时的时候触发,通过该方法统计
-
+
+
+
+ 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象
+
+ 资源对象
+
+
+
+ 归还对象给对象池的时候触发
+
+ 资源对象
+
+
+
+ 检查可用性
+
+ 资源对象
-
+
- 获取 obj.CsName 属性原始值(不经过 MapType)
+ 事件:可用时触发
-
-
+
- 设置 obj.CsName 属性值
+ 事件:不可用时触发
-
-
-
+
- 动态过滤条件
+ 所属对象池
-
+
- 属性名:Name
- 导航属性:Parent.Name
- 多表:b.Name
+ 在对象池中的唯一标识
-
+
- 操作符
+ 资源对象
-
+
- 值
+ 被获取的总次数
-
+
+ 最后获取时的时间
+
+
- Filters 下的逻辑运算符
+ 最后归还时的时间
-
+
- 子过滤条件,它与当前的逻辑关系是 And
- 注意:当前 Field 可以留空
+ 创建时间
-
+
+
+ 最后获取时的线程id
+
+
+
+
+ 最后归还时的线程id
+
+
+
+
+ 重置 Value 值
+
+
+
- like
+ 对象池管理类
+ 对象类型
-
+
- =
- Equal/Equals/Eq 效果相同
+ 后台定时检查可用性
+
-
+
- =
- Equal/Equals/Eq 效果相同
+ 创建对象池
+ 池大小
+ 池内对象的创建委托
+ 获取池内对象成功后,进行使用前操作
-
+
- =
- Equal/Equals/Eq 效果相同
+ 创建对象池
+ 策略
-
+
- <>
+ 获取可用资源,或创建资源
+
-
+
- >
+ 用于解决多实例情况下的静态集合缓存问题
-
+
- >=
+
+ String resources used in FreeSql exceptions, etc.
+
+
+ These strings are exposed publicly for use by database providers and extensions.
+ It is unusual for application code to need these strings.
+
-
+
- <
+ 重写当前线程的 CurrentUICulture 属性,对
+ 使用此强类型资源类的所有资源查找执行重写。
-
+
- <=
+ [Table(AsTable = "{asTable}")] 特性值格式错误
-
+
- >= and <
- 此时 Value 的值格式为逗号分割:value1,value2 或者数组
+ [Table(AsTable = xx)] 设置的属性名 {atmGroupsValue} 不是 DateTime 类型
-
+
- >= and <
- 此时 Value 的值格式为逗号分割:date1,date2 或者数组
- 这是专门为日期范围查询定制的操作符,它会处理 date2 + 1,比如:
+ {name}: Failed to get resource {statistics}
+
+
+
- 导航属性 {trytbTypeName}.{pnvName} 没有找到对应的字段,如:{pnvName}{findtbrefPkCsName}、{pnvName}_{findtbrefPkCsName}。或者使用 [Navigate] 特性指定关系映射。
+ 导航属性 {trytbTypeName}.{pnvName} 没有找到对应的字段,如:{pnvName}{findtbrefPkCsName}、{pnvName}_{findtbrefPkCsName}。或者使用 [Navigate] 特性指定
+
+
+ 未实现该功能
-
+
- 导航属性 {trytbTypeName}.{pnvName} 解析错误,实体类型 {trytcTypeName} 缺少主键标识,[Column(IsPrimary = true)]
+ 未实现错误,请反馈给作者
-
+
- 导航属性 {trytbTypeName}.{pnvName} 解析错误,{trytbCsName}.{trycolCsName} 和 {tbrefCsName}.{tbrefPrimarysCsName} 类型不一致
+ 找不到 {name}
-
+
- 导航属性 {trytbTypeName}.{pnvName} 特性 [Navigate] 解析错误,在 {tbrefTypeName} 未找到属性:{bi}
+ FreeSql.Provider.{providerName} 未实现 Skip/Offset 功能,如果需要分页请使用判断上一次 id
-
+
- {tableTypeDisplayCsharp} 没有定义主键,无法使用 SetSource,请尝试 SetDto 或者 SetSource 指定临时主键
+ 对象池
-
+
- 没有定义属性
+ 旧表(OldName):{tboldname} 存在,数据库已存在 {tbname} 表,无法改名
-
+
- 未实现
+ OnConflictDoUpdate 功能要求实体类必须设置 IsPrimary 属性
-
+
- 未实现函数表达式 {exp} 解析
+ Oracle CodeFirst 不支持代码创建 tablespace 与 schemas {tbname}
-
+
- 未实现函数表达式 {exp} 解析,参数 {expArguments} 必须为常量
+ 解析失败 {callExpMethodName} {message},提示:可以使用扩展方法 IQueryable.RestoreToSelect() 还原为 ISelect 再查询
-
+
- 未实现函数表达式 {exp} 解析,如果正在操作导航属性集合,请使用 .AsSelect().{exp3MethodName}({exp3ArgumentsCount})
+ fsql.InsertOrUpdate + IfExistsDoNothing + {providerName}要求实体类 {tableCsName} 必须有主键
-
+
- 未实现 MemberAccess 下的 Constant
+ SelectMany 错误的类型:{typeFullName}
-
+
- 未实现 {name}
+ 从库
-
+
- 不支持
+ 类型 {objentityTypeFullName} 不可迁移
-
+
- {dataType} 不支持 OrderByRandom 随机排序
+ 类型 {objentityTypeFullName} 不可迁移,可迁移属性0个
-
+
- {property} 不是有效的导航属性
+ 未实现 {columnDbTypeTextFull} 类型映射
-
+
- {dbName} 找不到列 {memberName}
+ 错误的参数设置:{args}
-
+
- 找不到 {CsName} 对应的列
+ {qoteSql} is NULL,除非设置特性 [Column(IsNullable = false)]
-
+
- 找不到属性:{memberName}
+ 分表字段值 "{dt}" 不能小于 "{beginTime} "
-
+
- 找不到属性名 {proto}
+ 分表字段值不能为 null
-
+
- Custom 找不到对应的{{ 反射信息 }}:{fiValueCustomArray}
+ 分表字段值 "{columnValue}" 不能转化成 DateTime
-
+
- Custom 找不到对应的{{ 静态方法名 }}:{fiValueCustomArray}
+ 分表字段值 "{dt}" 未匹配到分表名
-
+
- [Table(AsTable = xx)] 设置的属性名 {atmGroupsValue} 不存在
+ T2 类型错误
-
+
- 未指定 UseConnectionString 或者 UseConnectionFactory
+ tableName 格式错误,示例:“log_{yyyyMMdd}”
-
+
- 【{policyName}】ObjectPool.{GetName}() timeout {totalSeconds} seconds, see: https://github.com/dotnetcore/FreeSql/discussions/1081
+ {Type}.AsType 参数错误,请传入正确的实体类型
-
+
- 【{policyName}】ObjectPool.GetAsync() The queue is too long. Policy.AsyncGetCapacity = {asyncGetCapacity}
+ {thatFullName} 类型无法访问构造函数
-
+
- 【OneToMany】导航属性 {trytbTypeName}.{pnvName} 在 {tbrefCsName} 中没有找到对应的字段,如:{findtrytb}{findtrytbPkCsName}、{findtrytb}_{findtrytbPkCsName}
+ {name} 类型错误
-
+
- 【OneToMany】导航属性 {trytbTypeName}.{pnvName} 解析错误,{trytbCsName}.{trytbPrimarysCsName} 和 {tbrefCsName}.{trycolCsName} 类型不一致
+ {Type}.AsType 参数不支持指定为 object
-
+
- 、{refpropName}{findtrytbPkCsName}、{refpropName}_{findtrytbPkCsName}。或者使用 [Navigate] 特性指定关系映射。
+ 类型 {typeofFullName} 错误,不能使用 IncludeMany
-
+
- 参数 field 未指定
+ 无法解析表达式:{exp}
-
+
- {property} 参数错误,它不是集合属性,必须为 IList<T> 或者 ICollection<T>
+ 无法解析表达式方法 {exp3tmpCallMethodName}
-
+
- {property} 参数错误,它不是有效的导航属性
+ 请使用 fsql.InsertDict(dict) 方法插入字典数据
-
+
- {where} 参数错误,{keyval} 不是有效的属性名,在实体类 {reftbTypeDisplayCsharp} 无法找到
+ C#: that >= between && that <= and
+ SQL: that BETWEEN between AND and
+
+
+
+
-
+
- {property} 参数错误,格式 "TopicId=Id,多组使用逗号连接"
+ 注意:这个方法和 Between 有细微区别
+ C#: that >= start && that < end
+ SQL: that >= start and that < end
+
+
+
+
-
+
- 解析失败 {callExpMethodName} {message}
+ 获取 Type 的原始 c# 文本表示
+
+
+
-
+
- 【{policyName}】The ObjectPool has been disposed, see: https://github.com/dotnetcore/FreeSql/discussions/1079
+ 测量两个经纬度的距离,返回单位:米
+ 经纬坐标1
+ 经纬坐标2
+ 返回距离(单位:米)
-
+
- 【{policyName}】状态不可用,等待后台检查程序恢复方可使用。{UnavailableExceptionMessage}
+ 将 IEnumable<T> 转成 ISelect<T>,以便使用 FreeSql 的查询功能。此方法用于 Lambda 表达式中,快速进行集合导航的查询。
+
+
+
-
+
- 属性{trytbVersionColumnCsName} 被标注为行锁(乐观锁)(IsVersion),但其必须为数字类型 或者 byte[] 或者 string,并且不可为 Nullable
+ 多表查询
+
-
+
- properties 参数不能为空
+ 本方法实现从已知的内存 List 数据,进行和 ISelect.IncludeMany 相同功能的贪婪加载
+ 示例:new List<Song>(new[] { song1, song2, song3 }).IncludeMany(fsql, a => a.Tags);
+ 文档:https://github.com/dotnetcore/FreeSql/wiki/%E8%B4%AA%E5%A9%AA%E5%8A%A0%E8%BD%BD
+
+
+
+
+ 选择一个集合的导航属性,如: .IncludeMany(a => a.Tags)
+ 可以 .Where 设置临时的关系映射,如: .IncludeMany(a => a.Tags.Where(tag => tag.TypeId == a.Id))
+ 可以 .Take(5) 每个子集合只取5条,如: .IncludeMany(a => a.Tags.Take(5))
+ 可以 .Select 设置只查询部分字段,如: (a => new TNavigate { Title = a.Title })
+
+ 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?)
+
-
+
- {property} 属性名无法找到
+ 本方法实现从已知的内存 List 数据,进行和 ISelect.IncludeMany/Include 相同功能的贪婪加载
+ 集合:new List<Song>(new[] { song1, song2, song3 }).IncludeByPropertyName(fsql, "Tags", "ParentId=Id", 5, "Id,Name");
+ 普通:new List<Song>(new[] { song1, song2, song3 }).IncludeByPropertyName(fsql, "Catetory");
+ ---普通属性 where/take/select 参数将无效
+ 文档:https://github.com/dotnetcore/FreeSql/wiki/%E8%B4%AA%E5%A9%AA%E5%8A%A0%E8%BD%BD
+
+
+
+ 选择一个集合或普通属性
+ 设置临时的子集合关系映射,格式:子类属性=T1属性,多组以逗号分割
+ 设置子集合只取条数
+ 设置子集合只查询部分字段
+
+
-
+
- Range 要求 Value 应该逗号分割,并且长度为 2
+ 查询数据,加工为树型 List 返回
+ 注意:实体需要配置父子导航属性
+
+
+
-
+
- 回滚
+ 使用递归 CTE 查询树型的所有子记录,或者所有父记录。
+ 通过测试的数据库:MySql8.0、SqlServer、PostgreSQL、Oracle、Sqlite、Firebird、达梦、人大金仓、翰高
+ 返回隐藏字段:.ToList(a => new { item = a, level = "a.cte_level", path = "a.cte_path" })
+ * v2.0.0 兼容 MySql5.6 向上或向下查询,但不支持 pathSelector/pathSeparator 详细:https://github.com/dotnetcore/FreeSql/issues/536
+
+
+ false(默认):由父级向子级的递归查询true:由子级向父级的递归查询
+ 路径内容选择
+ 连接路径内容
+ 递归层级
+
-
+
- 运行时错误,反射获取 IncludeMany 方法失败
+ 随机排序
+ 支持:MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/金仓/神通
+ 不支持:MsAcess
+
-
+
- 蛋疼的 Access 插入只能一条一条执行,不支持 values(..),(..) 也不支持 select .. UNION ALL select ..
+ 插入数据字典 Dictionary<string, object>
+
+
-
+
- BaseEntity.Initialization 初始化错误,获取到 IFreeSql 是 null
+ 插入数据字典,传入 Dictionary<string, object> 集合
+
+
-
+
- 【{thisName}】Block access and wait for recovery: {exMessage}
+ 更新数据字典 Dictionary<string, object>
+
+
-
+
- 无法将 IQueryable<{typeofName}> 转换为 ISelect<{typeofName}>,因为他的实现不是 FreeSql.Extensions.Linq.QueryableProvider
+ 更新数据字典,传入 Dictionary<string, object> 集合
+
+
-
+
- 连接字符串错误
+ 插入或更新数据字典,此功能依赖数据库特性(低版本可能不支持),参考如下:
+ MySql 5.6+: on duplicate key update
+ PostgreSQL 9.4+: on conflict do update
+ SqlServer 2008+: merge into
+ Oracle 11+: merge into
+ Sqlite: replace into
+ 达梦: merge into
+ 人大金仓:on conflict do update
+ 神通:merge into
+ MsAccess:不支持
+
+
-
+
- 【{thisName}】连接字符串错误,请检查。
+ 删除数据字典 Dictionary<string, object>
+
+
-
+
- 连接字符串错误,或者检查项目属性 > 生成 > 目标平台:x86 | x64,或者改用 FreeSql.Provider.SqliteCore 访问 arm 平台
+ 删除数据字典,传入 Dictionary<string, object> 集合
+
+
-
+
- 【{thisName}】连接字符串错误,请检查。或者检查项目属性 > 生成 > 目标平台:x86 | x64,或者改用 FreeSql.Provider.SqliteCore 访问 arm 平台
+ 原生sql语法条件,Where("col = @xxx", new { xxx = 1 })
+ 提示:parms 参数还可以传 Dictionary<string, object>
+ sql语法条件
+ 参数
+
-
+
- FreeSql.Provider.CustomAdapter 无法使用 CreateCommand
+ 原生sql语法条件,Where("col = @xxx", new { xxx = 1 })
+ 提示:parms 参数还可以传 Dictionary<string, object>
+ sql语法条件
+ 参数
+
-
+
- FreeSql.Provider.CustomAdapter 仅支持 UseConnectionFactory 方式构建 IFreeSql
+ 使用 and 拼接两个 lambda 表达式
+
-
+
- 达梦 CodeFirst 不支持代码创建 tablespace 与 schemas {tbname}
+ 使用 and 拼接两个 lambda 表达式
+
+ true 时生效
+
+
-
+
- -DB 参数错误,未提供 ConnectionString
+ 使用 or 拼接两个 lambda 表达式
+
-
+
- -DB 参数错误,格式为:MySql,ConnectionString
+ 使用 or 拼接两个 lambda 表达式
+
+ true 时生效
+
+
-
+
- -DB 参数错误,不支持的类型:"{dbargs}"
+ 将 lambda 表达式取反
+
+ true 时生效
+
-
+
- {method} 是 FreeSql.Provider.{provider} 特有的功能
+ 使用 and 拼接两个 lambda 表达式
+
-
+
- fsql.InsertOrUpdate Sqlite 无法完成 UpdateColumns 操作
+ 使用 and 拼接两个 lambda 表达式
+
+ true 时生效
+
+
-
+
- 主库
+ 使用 or 拼接两个 lambda 表达式
+
-
+
- MygisGeometry.Parse 未实现 "{wkt}"
+ 使用 or 拼接两个 lambda 表达式
+
+ true 时生效
+
+
-
+
- -NameOptions 参数错误,格式为:0,0,0,0
+ 将 lambda 表达式取反
+
+ true 时生效
+
-
+
- 未实现该功能
+ 使用 and 拼接两个 lambda 表达式
+
-
+
- 未实现错误,请反馈给作者
+ 使用 and 拼接两个 lambda 表达式
+
+ true 时生效
+
+
-
+
- 找不到 {name}
+ 使用 or 拼接两个 lambda 表达式
+
-
+
- FreeSql.Provider.{providerName} 未实现 Skip/Offset 功能,如果需要分页请使用判断上一次 id
+ 使用 or 拼接两个 lambda 表达式
+
+ true 时生效
+
+
-
+
- 对象池
+ 将 lambda 表达式取反
+
+ true 时生效
+
-
+
- 旧表(OldName):{tboldname} 存在,数据库已存在 {tbname} 表,无法改名
+ 使用 and 拼接两个 lambda 表达式
+
-
+
- OnConflictDoUpdate 功能要求实体类必须设置 IsPrimary 属性
+ 使用 and 拼接两个 lambda 表达式
+
+ true 时生效
+
+
-
+
- Oracle CodeFirst 不支持代码创建 tablespace 与 schemas {tbname}
+ 使用 or 拼接两个 lambda 表达式
+
-
+
- 解析失败 {callExpMethodName} {message},提示:可以使用扩展方法 IQueryable.RestoreToSelect() 还原为 ISelect 再查询
+ 使用 or 拼接两个 lambda 表达式
+
+ true 时生效
+
+
-
+
- fsql.InsertOrUpdate + IfExistsDoNothing + {providerName}要求实体类 {tableCsName} 必须有主键
+ 将 lambda 表达式取反
+
+ true 时生效
+
-
+
- SelectMany 错误的类型:{typeFullName}
+ 使用 and 拼接两个 lambda 表达式
+
-
+
- 从库
+ 使用 and 拼接两个 lambda 表达式
-
-
-
- 类型 {objentityTypeFullName} 不可迁移
-
-
-
-
- 类型 {objentityTypeFullName} 不可迁移,可迁移属性0个
-
-
-
-
- 未实现 {columnDbTypeTextFull} 类型映射
-
-
-
-
- 错误的参数设置:{args}
-
-
-
-
- {qoteSql} is NULL,除非设置特性 [Column(IsNullable = false)]
-
-
-
-
- 分表字段值 "{dt}" 不能小于 "{beginTime} "
-
-
-
-
- 分表字段值不能为 null
-
-
-
-
- 分表字段值 "{columnValue}" 不能转化成 DateTime
-
-
-
-
- 分表字段值 "{dt}" 未匹配到分表名
-
-
-
-
- T2 类型错误
-
-
-
-
- tableName 格式错误,示例:“log_{yyyyMMdd}”
-
-
-
-
- {Type}.AsType 参数错误,请传入正确的实体类型
-
-
-
-
- {thatFullName} 类型无法访问构造函数
-
-
-
-
- {name} 类型错误
-
-
-
-
- {Type}.AsType 参数不支持指定为 object
-
-
-
-
- 类型 {typeofFullName} 错误,不能使用 IncludeMany
-
-
-
-
- 无法解析表达式:{exp}
-
-
-
-
- 无法解析表达式方法 {exp3tmpCallMethodName}
-
-
-
-
- 请使用 fsql.InsertDict(dict) 方法插入字典数据
-
-
-
-
- 动态构建Class Type
-
-
-
-
-
- 根据字典,创建 table 对应的实体对象
-
-
-
+
+ true 时生效
+
-
+
- 根据实体对象,创建 table 对应的字典
+ 使用 or 拼接两个 lambda 表达式
-
-
-
+
- C#: that >= between && that <= and
- SQL: that BETWEEN between AND and
+ 使用 or 拼接两个 lambda 表达式
-
-
-
+
+ true 时生效
+
-
+
- 注意:这个方法和 Between 有细微区别
- C#: that >= start && that < end
- SQL: that >= start and that < end
+ 将 lambda 表达式取反
-
-
-
+
+ true 时生效
-
+
- 获取 Type 的原始 c# 文本表示
+ 生成类似Mongodb的ObjectId有序、不重复Guid
-
-
-
-
- 测量两个经纬度的距离,返回单位:米
-
- 经纬坐标1
- 经纬坐标2
- 返回距离(单位:米)
-
-
+
- 将 IEnumable<T> 转成 ISelect<T>,以便使用 FreeSql 的查询功能。此方法用于 Lambda 表达式中,快速进行集合导航的查询。
+ 插入数据
-
-
+
-
+
- 多表查询
+ 插入数据,传入实体
+
+
-
+
- 本方法实现从已知的内存 List 数据,进行和 ISelect.IncludeMany 相同功能的贪婪加载
- 示例:new List<Song>(new[] { song1, song2, song3 }).IncludeMany(fsql, a => a.Tags);
- 文档:https://github.com/dotnetcore/FreeSql/wiki/%E8%B4%AA%E5%A9%AA%E5%8A%A0%E8%BD%BD
+ 插入数据,传入实体数组
-
-
-
- 选择一个集合的导航属性,如: .IncludeMany(a => a.Tags)
- 可以 .Where 设置临时的关系映射,如: .IncludeMany(a => a.Tags.Where(tag => tag.TypeId == a.Id))
- 可以 .Take(5) 每个子集合只取5条,如: .IncludeMany(a => a.Tags.Take(5))
- 可以 .Select 设置只查询部分字段,如: (a => new TNavigate { Title = a.Title })
-
- 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?)
+
-
+
- 本方法实现从已知的内存 List 数据,进行和 ISelect.IncludeMany/Include 相同功能的贪婪加载
- 集合:new List<Song>(new[] { song1, song2, song3 }).IncludeByPropertyName(fsql, "Tags", "ParentId=Id", 5, "Id,Name");
- 普通:new List<Song>(new[] { song1, song2, song3 }).IncludeByPropertyName(fsql, "Catetory");
- ---普通属性 where/take/select 参数将无效
- 文档:https://github.com/dotnetcore/FreeSql/wiki/%E8%B4%AA%E5%A9%AA%E5%8A%A0%E8%BD%BD
+ 插入数据,传入实体集合
-
-
- 选择一个集合或普通属性
- 设置临时的子集合关系映射,格式:子类属性=T1属性,多组以逗号分割
- 设置子集合只取条数
- 设置子集合只查询部分字段
+
-
-
+
- 查询数据,加工为树型 List 返回
- 注意:实体需要配置父子导航属性
+ 插入数据,传入实体集合
-
+
-
+
- 使用递归 CTE 查询树型的所有子记录,或者所有父记录。
- 通过测试的数据库:MySql8.0、SqlServer、PostgreSQL、Oracle、Sqlite、Firebird、达梦、人大金仓、翰高
- 返回隐藏字段:.ToList(a => new { item = a, level = "a.cte_level", path = "a.cte_path" })
- * v2.0.0 兼容 MySql5.6 向上或向下查询,但不支持 pathSelector/pathSeparator 详细:https://github.com/dotnetcore/FreeSql/issues/536
+ 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下:
+ MySql 5.6+: on duplicate key update
+ PostgreSQL 9.4+: on conflict do update
+ SqlServer 2008+: merge into
+ Oracle 11+: merge into
+ Sqlite: replace into
+ 达梦: merge into
+ 人大金仓:on conflict do update
+ 神通:merge into
+ MsAccess:不支持
+ 注意区别:FreeSql.Repository 仓储也有 InsertOrUpdate 方法(不依赖数据库特性)
-
- false(默认):由父级向子级的递归查询true:由子级向父级的递归查询
- 路径内容选择
- 连接路径内容
- 递归层级
-
+
- 随机排序
- 支持:MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/金仓/神通
- 不支持:MsAcess
+ 修改数据
+
-
+
- 插入数据字典 Dictionary<string, object>
+ 修改数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1}
-
+
+ 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合
-
+
- 插入数据字典,传入 Dictionary<string, object> 集合
+ 查询数据
-
+
-
+
- 更新数据字典 Dictionary<string, object>
+ 查询数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1}
-
+
+ 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合
-
+
- 更新数据字典,传入 Dictionary<string, object> 集合
+ 删除数据
-
+
-
+
- 插入或更新数据字典,此功能依赖数据库特性(低版本可能不支持),参考如下:
- MySql 5.6+: on duplicate key update
- PostgreSQL 9.4+: on conflict do update
- SqlServer 2008+: merge into
- Oracle 11+: merge into
- Sqlite: replace into
- 达梦: merge into
- 人大金仓:on conflict do update
- 神通:merge into
- MsAccess:不支持
+ 删除数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1}
-
+
+ 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合
-
+
- 删除数据字典 Dictionary<string, object>
+ 开启事务(不支持异步)
+ v1.5.0 关闭了线程事务超时自动提交的机制
-
-
+ 事务体 () => {}
-
+
- 删除数据字典,传入 Dictionary<string, object> 集合
+ 开启事务(不支持异步)
+ v1.5.0 关闭了线程事务超时自动提交的机制
-
-
+
+ 事务体 () => {}
-
+
- 原生sql语法条件,Where("col = @xxx", new { xxx = 1 })
- 提示:parms 参数还可以传 Dictionary<string, object>
+ 数据库访问对象
- sql语法条件
- 参数
-
-
+
- 原生sql语法条件,Where("col = @xxx", new { xxx = 1 })
- 提示:parms 参数还可以传 Dictionary<string, object>
+ 所有拦截方法都在这里
- sql语法条件
- 参数
-
-
+
- 使用 and 拼接两个 lambda 表达式
+ CodeFirst 模式开发相关方法
-
-
+
- 使用 and 拼接两个 lambda 表达式
+ DbFirst 模式开发相关方法
-
- true 时生效
-
-
-
+
- 使用 or 拼接两个 lambda 表达式
+ 全局过滤设置,可默认附加为 Select/Update/Delete 条件
-
-
-
- 使用 or 拼接两个 lambda 表达式
-
-
- true 时生效
-
-
+
+
+
diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj
index d14a86433..870b76116 100644
--- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj
+++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj
@@ -20,7 +20,7 @@
-
+
@@ -31,6 +31,10 @@
Always
+
+
+
+
diff --git a/Providers/FreeSql.Provider.KingbaseES/KingbaseESAdo/KingbaseESAdo.cs b/Providers/FreeSql.Provider.KingbaseES/KingbaseESAdo/KingbaseESAdo.cs
index 167312313..e6f82931d 100644
--- a/Providers/FreeSql.Provider.KingbaseES/KingbaseESAdo/KingbaseESAdo.cs
+++ b/Providers/FreeSql.Provider.KingbaseES/KingbaseESAdo/KingbaseESAdo.cs
@@ -3,10 +3,13 @@
using FreeSql.Internal.Model;
using FreeSql.Internal.ObjectPool;
using Kdbndp;
+using Newtonsoft.Json.Linq;
using System;
using System.Collections;
+using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
+using System.Text;
using System.Threading;
namespace FreeSql.KingbaseES
@@ -43,9 +46,10 @@ public KingbaseESAdo(CommonUtils util, string masterConnectionString, string[] s
public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn)
{
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);
+ bool isdic;
if (param is bool || param is bool?)
return (bool)param ? "'t'" : "'f'";
else if (param is string)
@@ -62,6 +66,16 @@ public override object AddslashesProcessParam(object param, Type mapType, Column
else if (param is DateTime?)
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?)
{
var ts = (TimeSpan)param;
@@ -69,6 +83,31 @@ public override object AddslashesProcessParam(object param, Type mapType, Column
}
else if (param is 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) ||
+ param is IEnumerable>)
+ {
+ var pgdics = isdic ? param as Dictionary :
+ param as IEnumerable>;
+
+ 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)
return AddslashesIEnumerable(param, mapType, mapColumn);
diff --git a/Providers/FreeSql.Provider.KingbaseES/KingbaseESCodeFirst.cs b/Providers/FreeSql.Provider.KingbaseES/KingbaseESCodeFirst.cs
index 44c28eb76..a6a0b7eab 100644
--- a/Providers/FreeSql.Provider.KingbaseES/KingbaseESCodeFirst.cs
+++ b/Providers/FreeSql.Provider.KingbaseES/KingbaseESCodeFirst.cs
@@ -1,11 +1,17 @@
using FreeSql.Internal;
using FreeSql.Internal.Model;
using KdbndpTypes;
+using Newtonsoft.Json.Linq;
using System;
+using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
+using System.Net;
+using System.Net.NetworkInformation;
+using System.Numerics;
using System.Text;
+using System.Text.RegularExpressions;
namespace FreeSql.KingbaseES
{
@@ -36,22 +42,58 @@ public KingbaseESCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpressi
{ 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) },
+#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(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(KdbndpRange).FullName, CsToDb.New(KdbndpDbType.Range | KdbndpDbType.Integer, "int4range", "int4range NOT NULL", false, false, KdbndpRange.Empty) },{ typeof(KdbndpRange?).FullName, CsToDb.New(KdbndpDbType.Range | KdbndpDbType.Integer, "int4range", "int4range", false, true, null) },
+ { typeof(KdbndpRange).FullName, CsToDb.New(KdbndpDbType.Range | KdbndpDbType.Bigint, "int8range", "int8range NOT NULL", false, false, KdbndpRange.Empty) },{ typeof(KdbndpRange?).FullName, CsToDb.New(KdbndpDbType.Range | KdbndpDbType.Bigint, "int8range", "int8range", false, true, null) },
+ { typeof(KdbndpRange).FullName, CsToDb.New(KdbndpDbType.Range | KdbndpDbType.Numeric, "numrange", "numrange NOT NULL", false, false, KdbndpRange.Empty) },{ typeof(KdbndpRange?).FullName, CsToDb.New(KdbndpDbType.Range | KdbndpDbType.Numeric, "numrange", "numrange", false, true, null) },
+ { typeof(KdbndpRange).FullName, CsToDb.New(KdbndpDbType.Range | KdbndpDbType.Timestamp, "tsrange", "tsrange NOT NULL", false, false, KdbndpRange.Empty) },{ typeof(KdbndpRange?).FullName, CsToDb.New(KdbndpDbType.Range | KdbndpDbType.Timestamp, "tsrange", "tsrange", false, true, null) },
+
+ { typeof(Dictionary).FullName, CsToDb.New(KdbndpDbType.Hstore, "hstore", "hstore", false, null, new Dictionary()) },
};
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 GetDbInfoNoneArray(Type type)
+ {
+ if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return trydc;
if (type.IsArray) return null;
var enumType = type.IsEnum ? type : null;
- if (enumType == null && type.IsNullableType())
- {
- var genericTypes = type.GetGenericArguments();
- if (genericTypes.Length == 1 && genericTypes.First().IsEnum) enumType = genericTypes.First();
- }
+ if (enumType == null && type.IsNullableType() && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First();
if (enumType != null)
{
var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ?
@@ -65,7 +107,7 @@ public override DbInfoResult GetDbInfo(Type type)
_dicCsToDb.Add(type.FullName, newItem);
}
}
- return new DbInfoResult((int)newItem.type, newItem.dbtype, newItem.dbtypeFull, newItem.isnullable, newItem.defaultValue);
+ return newItem;
}
return null;
}
diff --git a/Providers/FreeSql.Provider.KingbaseES/KingbaseESDbFirst.cs b/Providers/FreeSql.Provider.KingbaseES/KingbaseESDbFirst.cs
index b3a23d6cb..20f0a4379 100644
--- a/Providers/FreeSql.Provider.KingbaseES/KingbaseESDbFirst.cs
+++ b/Providers/FreeSql.Provider.KingbaseES/KingbaseESDbFirst.cs
@@ -2,12 +2,16 @@
using FreeSql.Internal;
using FreeSql.Internal.Model;
using KdbndpTypes;
+using Newtonsoft.Json.Linq;
using System;
+using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Linq;
+using System.Net;
+using System.Net.NetworkInformation;
using System.Text;
using System.Text.RegularExpressions;
@@ -25,75 +29,175 @@ public KingbaseESDbFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression
_commonExpression = commonExpression;
}
- public int GetDbType(DbColumnInfo column) => (int)GetSqlDbType(column);
- KdbndpDbType GetSqlDbType(DbColumnInfo column)
+ public int GetDbType(DbColumnInfo column) => (int)GetKdbndpDbType(column);
+ KdbndpDbType GetKdbndpDbType(DbColumnInfo column)
{
var dbtype = column.DbTypeText;
var isarray = dbtype?.EndsWith("[]") == true;
if (isarray) dbtype = dbtype.Remove(dbtype.Length - 2);
- var ret = KdbndpDbType.Unknown;
+ KdbndpDbType ret = KdbndpDbType.Unknown;
switch (dbtype?.ToLower().TrimStart('_'))
{
- case "tinyint": ret = KdbndpDbType.Smallint; break;
+ case "smallint":
case "int2": ret = KdbndpDbType.Smallint; break;
+ case "integer":
case "int4": ret = KdbndpDbType.Integer; break;
+ case "bigint":
case "int8": ret = KdbndpDbType.Bigint; break;
case "numeric": ret = KdbndpDbType.Numeric; break;
+ case "real":
case "float4": ret = KdbndpDbType.Real; break;
+ case "double precision":
case "float8": ret = KdbndpDbType.Double; 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 "character varying":
case "varchar": ret = KdbndpDbType.Varchar; break;
case "text": ret = KdbndpDbType.Text; break;
- case "datetime": 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 "time": ret = KdbndpDbType.Time; break;
- case "timetz": ret = KdbndpDbType.Time; break;
- case "interval": ret = KdbndpDbType.Time; break;
+ case "timetz": ret = KdbndpDbType.TimeTz; break;
+ case "interval": ret = KdbndpDbType.Interval; break;
case "bool": ret = KdbndpDbType.Boolean; break;
- case "blob": ret = KdbndpDbType.Bytea; break;
case "bytea": ret = KdbndpDbType.Bytea; break;
case "bit": ret = KdbndpDbType.Bit; 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 "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 _dicDbToCs = new ConcurrentDictionary();
- static KingbaseESDbFirst()
- {
- var defaultDbToCs = new Dictionary() {
- { (int)KdbndpDbType.Smallint, new DbToCs("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(int), typeof(int?), "{0}.Value", "GetInt16") },
- { (int)KdbndpDbType.Integer, new DbToCs("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(long), typeof(long?), "{0}.Value", "GetInt32") },
- { (int)KdbndpDbType.Bigint, new DbToCs("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") },
- { (int)KdbndpDbType.Real, new DbToCs("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") },
- { (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.Varchar, new DbToCs("", "{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.Timestamp, new DbToCs("(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.Time, new DbToCs("(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.Bytea, new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") },
-
- { (int)KdbndpDbType.Uuid, new DbToCs("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid", typeof(Guid), typeof(Guid?), "{0}", "GetString") },
+ static readonly Dictionary _dicDbToCs = new Dictionary() {
+ { (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") },
+ { (int)KdbndpDbType.Bigint, ("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") },
+ { (int)KdbndpDbType.Numeric, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") },
+ { (int)KdbndpDbType.Real, ("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") },
+ { (int)KdbndpDbType.Double, ("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") },
+ { (int)KdbndpDbType.Money, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") },
+
+ { (int)KdbndpDbType.Char, ("", "{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, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") },
+
+ { (int)KdbndpDbType.Timestamp, ("(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.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, ("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") },
+ { (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.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?)", "{0}.ToKdbndpRange()", "{0}.ToString()", "KdbndpRange", typeof(KdbndpRange), typeof(KdbndpRange?), "{0}", "GetString") },
+ { (int)(KdbndpDbType.Range | KdbndpDbType.Bigint), ("(KdbndpRange?)", "{0}.ToKdbndpRange()", "{0}.ToString()", "KdbndpRange", typeof(KdbndpRange), typeof(KdbndpRange?), "{0}", "GetString") },
+ { (int)(KdbndpDbType.Range | KdbndpDbType.Numeric), ("(KdbndpRange?)", "{0}.ToKdbndpRange()", "{0}.ToString()", "KdbndpRange", typeof(KdbndpRange), typeof(KdbndpRange?), "{0}", "GetString") },
+ { (int)(KdbndpDbType.Range | KdbndpDbType.Timestamp), ("(KdbndpRange?)", "{0}.ToKdbndpRange()", "{0}.ToString()", "KdbndpRange", typeof(KdbndpRange), typeof(KdbndpRange?), "{0}", "GetString") },
+ { (int)(KdbndpDbType.Range | KdbndpDbType.TimestampTz), ("(KdbndpRange?)", "{0}.ToKdbndpRange()", "{0}.ToString()", "KdbndpRange", typeof(KdbndpRange), typeof(KdbndpRange?), "{0}", "GetString") },
+ { (int)(KdbndpDbType.Range | KdbndpDbType.Date), ("(KdbndpRange?)", "{0}.ToKdbndpRange()", "{0}.ToString()", "KdbndpRange", typeof(KdbndpRange), typeof(KdbndpRange?), "{0}", "GetString") },
+
+ { (int)KdbndpDbType.Hstore, ("(Dictionary)", "JsonConvert.DeserializeObject>({0})", "JsonConvert.SerializeObject({0})", "Dictionary