FreeSql 数据库列名 指定数据库旧的列名,修改实体属性命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库字段;否则将视为【新增字段】 数据库类型,如: varchar(255) 字符串长度,可使用特性 [MaxLength(255)] 主键 自增标识 是否可DBNull 忽略此列,不迁移、不插入 设置行锁(乐观锁)版本号,每次更新累加版本号,若更新整个实体时会附带当前的版本号判断(修改失败时抛出异常) 类型映射,除了可做基本的类型映射外,特别介绍的功能: 1、将 enum 属性映射成 typeof(string) 2、将 对象 属性映射成 typeof(string),请安装扩展包 FreeSql.Extensions.JsonMap 创建表时字段的位置(场景:实体继承后设置字段顺序),规则如下: >0时排前面,1,2,3... =0时排中间(默认) <0时排后面,...-3,-2,-1 该字段是否可以插入,默认值true,指定为false插入时该字段会被忽略 该字段是否可以更新,默认值true,指定为false更新时该字段会被忽略 标记属性为数据库服务器时间(utc/local),在插入的时候使用类似 getdate() 执行 设置长度,针对 string/byte[] 类型避免 DbType 的繁琐设置 提示:也可以使用 [MaxLength(100)] --- StringLength = 100 时,对应 DbType: MySql -> varchar(100) SqlServer -> nvarchar(100) PostgreSQL -> varchar(100) Oracle -> nvarchar2(100) Sqlite -> nvarchar(100) --- StringLength < 0 时,对应 DbType: MySql -> text (StringLength = -2 时,对应 longtext) SqlServer -> nvarchar(max) PostgreSQL -> text Oracle -> nclob Sqlite -> text v1.6.0+ byte[] 支持设置 StringLength 执行 Insert 方法时使用此值 注意:如果是 getdate() 这种请可考虑使用 ServerTime,因为它对数据库间作了适配 decimal/numeric 类型的长度 decimal/numeric 类型的小数位长度 数据库列名 指定数据库旧的列名,修改实体属性命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库字段;否则将视为【新增字段】 数据库类型,如: varchar(255) 主键 自增标识 是否可DBNull 忽略此列,不迁移、不插入 乐观锁 类型映射,比如:可将 enum 属性映射成 typeof(string) 创建表时字段位置,规则如下: >0时排前面 =0时排中间(默认) <0时排后面 该字段是否可以插入,默认值true,指定为false插入时该字段会被忽略 该字段是否可以更新,默认值true,指定为false更新时该字段会被忽略 标记属性为数据库服务器时间(utc/local),在插入的时候使用类似 getdate() 执行 设置长度,针对 string 类型避免 DbType 的繁琐设置 --- StringLength = 100 时,对应 DbType: MySql -> varchar(100) SqlServer -> nvarchar(100) PostgreSQL -> varchar(100) Oracle -> nvarchar2(100) Sqlite -> nvarchar(100) --- StringLength = -1 时,对应 DbType: MySql -> text SqlServer -> nvarchar(max) PostgreSQL -> text Oracle -> nvarchar2(4000) Sqlite -> text 执行 Insert 方法时使用此值 注意:如果是 getdate() 这种请可考虑使用 ServerTime,因为它对数据库间作了适配 decimal/numeric 类型的长度/小数位长度 总长度 小数位长度 自定义表达式函数解析 注意:请使用静态方法、或者在类上标记 自定义表达式函数解析的时候,指定参数不解析 SQL,而是直接传进来 数据库类型,可用于适配多种数据库环境 已解析的表达式中参数内容 表达式原始值 主对象的参数化对象,可重塑其属性 可附加参数化对象 注意:本属性只有 Where 的表达式解析才可用 将 c# 对象转换为 SQL 返回表达式函数表示的 SQL 字符串 获取实体元数据 解析表达式 索引设置,如:[Index("{tablename}_idx_01", "name")] 索引设置,如:[Index("{tablename}_idx_01", "name")] 索引名v1.7.0 增加占位符 {TableName} 表名区分索引名 (解决 AsTable 分表 CodeFirst 导致索引名重复的问题) 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC 索引设置,如:[Index("{tablename}_idx_01", "name", true)] 索引名v1.7.0 增加占位符 {TableName} 表名区分索引名 (解决 AsTable 分表 CodeFirst 导致索引名重复的问题) 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC 是否唯一 索引名 v1.7.0 增加占位符 {TableName} 表名区分索引名 (解决 AsTable 分表 CodeFirst 导致索引名重复的问题) 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC 是否唯一 手工绑定 OneToMany、ManyToOne 导航关系 手工绑定 ManyToMany 导航关系 主键名 数据库表名 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 禁用 CodeFirst 同步结构迁移 数据库表名 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 禁用 CodeFirst 同步结构迁移 导航关系Fluent,与 NavigateAttribute 对应 多对多关系的中间实体类型 设置实体的索引 索引名 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC 是否唯一 数据库表名 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 禁用 CodeFirst 同步结构迁移 导航关系Fluent,与 NavigateAttribute 对应 多对多关系的中间实体类型 设置实体的索引 索引名 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC 是否唯一 所属表 列名 映射到 C# 类型 数据库枚举类型int值 数据库类型,字符串,varchar 数据库类型,字符串,varchar(255) 最大长度 主键 自增标识 是否可DBNull 备注 数据库默认值 字段位置 枚举类型标识 枚举项 唯一标识 SqlServer下是Owner、PostgreSQL下是Schema、MySql下是数据库名 表名 表备注,SqlServer下是扩展属性 MS_Description 表/视图 自增列 主键/组合 唯一键/组合 索引/组合 外键 类型标识 枚举项 通用的 Odbc 实现,只能做基本的 Crud 操作 不支持实体结构迁移、不支持分页(只能 Take 查询) 通用实现为了让用户自己适配更多的数据库,比如连接 mssql 2000、db2 等数据库 默认适配 SqlServer,可以继承后重新适配 FreeSql.Odbc.Default.OdbcAdapter,最好去看下代码 适配新的 OdbcAdapter,请在 FreeSqlBuilder.Build 之后调用 IFreeSql.SetOdbcAdapter 方法设置 武汉达梦数据库有限公司,基于 Odbc 的实现 Microsoft Office Access 是由微软发布的关联式数据库管理系统 武汉达梦数据库有限公司,基于 DmProvider.dll 的实现 北京人大金仓信息技术股份有限公司,基于 Odbc 的实现 天津神舟通用数据技术有限公司,基于 System.Data.OscarClient.dll 的实现 获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值时,返回 null 当Guid无值时,会生成有序的新值 获取实体的主键值,多个主键返回数组 获取实体的属性值 获取实体的所有数据,以 (1, 2, xxx) 的形式 使用新实体的值,复盖旧实体的值 使用新实体的主键值,复盖旧实体的主键值 设置实体中主键内的自增字段值(若存在) 获取实体中主键内的自增字段值(若存在) 清除实体的主键值,将自增、Guid类型的主键值清除 清除实体的主键值,将自增、Guid类型的主键值清除 对比两个实体值,返回相同/或不相同的列名 设置实体中某属性的数值增加指定的值 设置实体中某属性的值 缓存执行 IUpdate.Set SqlExt 是利用自定表达式函数解析功能,解析默认常用的SQL函数,欢迎 PR rank() over(order by ...) dense_rank() over(order by ...) count() over(order by ...) sum(..) over(order by ...) avg(..) over(order by ...) max(..) over(order by ...) min(..) over(order by ...) SqlServer row_number() over(order by ...) case when .. then .. end MySql group_concat(distinct .. order by .. separator ..) PostgreSQL string_agg(.., ..) 使用连接串(推荐) 数据库类型 数据库连接串 提供者的类型,一般不需要指定,如果一直提示“缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载”的错误,说明反射获取不到类型,此时该参数可排上用场 使用从数据库,支持多个 从数据库连接串 使用自定义数据库连接对象(放弃内置对象连接池技术) 数据库类型 数据库连接对象创建器 提供者的类型,一般不需要指定,如果一直提示“缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载”的错误,说明反射获取不到类型,此时该参数可排上用场 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 注意:生产环境中谨慎使用 true:运行时检查自动同步结构, false:不同步结构(默认) 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 本功能会影响 IFreeSql 首次访问的速度。 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 不使用命令参数化执行,针对 Insert/Update,也可临时使用 IInsert/IUpdate.NoneParameter() 是否生成命令参数化执行,针对 lambda 表达式解析 注意:常量不会参数化,变量才会做参数化 var id = 100; fsql.Select<T>().Where(a => a.id == id) 会参数化 fsql.Select<T>().Where(a => a.id == 100) 不会参数化 延时加载导航属性对象,导航属性需要声明 virtual 监视数据库命令对象 执行前 执行后,可监视执行性能 实体类名 -> 数据库表名,命名转换(类名、属性名都生效) 优先级小于 [Table(Name = "xxx")]、[Column(Name = "xxx")] 监听 AppDomain.CurrentDomain.ProcessExit/Console.CancelKeyPress 事件自动释放连接池 默认值: true 转小写同步结构 true:转小写, false:不转 转大写同步结构 true:转大写, false:不转 自动转换实体属性名称 Entity Property -> Db Filed *不会覆盖 [Column] 特性设置的Name 指定事务对象 指定事务对象 lambda表达式条件,仅支持实体基础成员(不包含导航对象) 若想使用导航对象,请使用 ISelect.ToDelete() 方法 lambda表达式条件 原生sql语法条件,Where("id = ?id", new { id = 1 }) 提示:parms 参数还可以传 Dictionary<string, object> sql语法条件 参数 传入实体,将主键作为条件 实体 传入实体集合,将主键作为条件 实体集合 传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 是否标识为NOT 禁用全局过滤功能,不传参数时将禁用所有 零个或多个过滤器名字 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; 动态Type,在使用 Delete<object> 后使用本方法,指定实体类型 返回即将执行的SQL语句 执行SQL语句,返回影响的行数 执行SQL语句,返回被删除的记录 注意:此方法只有 Postgresql/SqlServer 有效果 指定事务对象 指定事务对象 追加准备插入的实体 实体 追加准备插入的实体 实体 追加准备插入的实体集合 实体集合 只插入的列,InsertColumns(a => a.Name) | InsertColumns(a => new{a.Name,a.Time}) | InsertColumns(a => new[]{"name","time"}) lambda选择列 只插入的列 属性名,或者字段名 忽略的列,IgnoreColumns(a => a.Name) | IgnoreColumns(a => new{a.Name,a.Time}) | IgnoreColumns(a => new[]{"name","time"}) lambda选择列 忽略的列 属性名,或者字段名 指定可插入自增字段 不使用参数化,可通过 IFreeSql.CodeFirst.IsNotCommandParameter 全局性设置 是否不使用参数化 批量执行选项设置,一般不需要使用该方法 各数据库 values, parameters 限制不一样,默认设置: MySql 5000 3000 PostgreSQL 5000 3000 SqlServer 1000 2100 Oracle 500 999 Sqlite 5000 999 若没有事务传入,内部(默认)会自动开启新事务,保证拆包执行的完整性。 指定根据 values 上限数量拆分执行 指定根据 parameters 上限数量拆分执行 是否自动开启事务 批量执行时,分批次执行的进度状态 批量执行时的回调委托 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; 动态Type,在使用 Insert<object> 后使用本方法,指定实体类型 返回即将执行的SQL语句 执行SQL语句,返回影响的行数 执行SQL语句,返回自增值 注意:请检查实体类是否标记了 [Column(IsIdentity = true)] 执行SQL语句,返回插入后的记录 注意:此方法只有 Postgresql/SqlServer 有效果 返回 DataTable 以便做 BulkCopy 数据做准备 此方法会处理: 类型、表名、字段名映射 IgnoreColumns、InsertColumns 指定事务对象 指定事务对象 添加或更新,设置实体 实体 添加或更新,设置实体集合 实体集合 当记录存在时,什么都不做 换句话:只有记录不存在时才插入 当记录存在时,指定只更新的字段,UpdateColumns(a => a.Name) | UpdateColumns(a => new{a.Name,a.Time}) | UpdateColumns(a => new[]{"name","time"}) lambda选择列 当记录存在时,指定只更新的字段 属性名,或者字段名 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; 动态Type,在使用 Update<object> 后使用本方法,指定实体类型 返回即将执行的SQL语句 执行SQL语句,返回影响的行数 自动产生 as1, as2, as3 .... 字段别名 这种方法可以最大程度防止多表,存在相同字段的问题 使用属性名作为字段别名 指定事务对象 指定连接对象 审核或跟踪 ToList 即将返回的数据 执行SQL查询,返回 DataTable 以字典的形式返回查询结果 注意:字典的特点会导致返回的数据无序 执行SQL查询,返回 T1 实体所有字段的记录,记录不存在时返回 Count 为 0 的列表 注意: 1、ToList(a => a) 可以返回 a 所有实体 2、ToList(a => new { a }) 这样也可以 3、ToList((a, b, c) => new { a, b, c }) 这样也可以 4、abc 怎么来的?请试试 fsql.Select<T1, T2, T3>() false: 返回 2级 LeftJoin/InnerJoin/RightJoin 对象;true: 返回所有 LeftJoin/InnerJoin/RightJoin 的导航数据 执行SQL查询,分块返回数据,可减少内存开销。比如读取10万条数据,每次返回100条处理。 数据块的大小 处理数据块 false: 返回 2级 LeftJoin/InnerJoin/RightJoin 对象;true: 返回所有 LeftJoin/InnerJoin/RightJoin 的导航数据 执行SQL查询,返回 field 指定字段的记录,并以元组或基础类型(int,string,long)接收,记录不存在时返回 Count 为 0 的列表 执行SQL查询,返回 T1 实体所有字段的第一条记录,记录不存在时返回 null 执行SQL查询,返回 T1 实体所有字段的第一条记录,记录不存在时返回 null 将查询转为删除对象,以便支持导航对象或其他查询功能删除数据,如下: fsql.Select<T1>().Where(a => a.Options.xxx == 1).ToDelete().ExecuteAffrows() 注意:此方法不是将数据查询到内存循环删除,上面的代码产生如下 SQL 执行: DELETE FROM `T1` WHERE id in (select a.id from T1 a left join Options b on b.t1id = a.id where b.xxx = 1) 复杂删除使用该方案的好处: 1、删除前可预览测试数据,防止错误删除操作; 2、支持更加复杂的删除操作(IDelete 默认只支持简单的操作); 将查询转为更新对象,以便支持导航对象或其他查询功能更新数据,如下: fsql.Select<T1>().Where(a => a.Options.xxx == 1).ToUpdate().Set(a => a.Title, "111").ExecuteAffrows() 注意:此方法不是将数据查询到内存循环更新,上面的代码产生如下 SQL 执行: UPDATE `T1` SET Title = '111' WHERE id in (select a.id from T1 a left join Options b on b.t1id = a.id where b.xxx = 1) 复杂更新使用该方案的好处: 1、更新前可预览测试数据,防止错误更新操作; 2、支持更加复杂的更新操作(IUpdate 默认只支持简单的操作); 设置表名规则,可用于分库/分表,参数1:实体类型;参数2:默认表名;返回值:新表名; 设置多次,可查询分表后的多个子表记录,以 UNION ALL 形式执行。 如:select.AsTable((type, oldname) => "table_1").AsTable((type, oldname) => "table_2").AsTable((type, oldname) => "table_3").ToSql(a => a.Id); select * from (SELECT a."Id" as1 FROM "table_1" a) ftb UNION ALL select * from (SELECT a."Id" as1 FROM "table_2" a) ftb UNION ALL select * from (SELECT a."Id" as1 FROM "table_3" a) ftb 还可以这样:select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList() 设置别名规则,可用于拦截表别名,实现类似 sqlserver 的 with(nolock) 需求 如:select.AsAlias((_, old) => $"{old} with(lock)") 动态Type,在使用 Select<object> 后使用本方法,指定实体类型 返回即将执行的SQL语句 指定字段 执行SQL查询,是否有记录 查询的记录数量 查询的记录数量,以参数out形式返回 返回的变量 指定从主库查询(默认查询从库) 左联查询,使用导航属性自动生成SQL 表达式 联接查询,使用导航属性自动生成SQL 表达式 右联查询,使用导航属性自动生成SQL 表达式 左联查询,指定关联的实体类型 关联的实体类型 表达式 联接查询,指定关联的实体类型 关联的实体类型 表达式 右联查询,指定关联的实体类型 关联的实体类型 表达式 左联查询,使用原生sql语法,LeftJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) 提示:parms 参数还可以传 Dictionary<string, object> sql语法条件 参数 联接查询,使用原生sql语法,InnerJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) 提示:parms 参数还可以传 Dictionary<string, object> sql语法条件 参数 右联查询,使用原生sql语法,RightJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) 提示:parms 参数还可以传 Dictionary<string, object> sql语法条件 参数 在 JOIN 位置插入 SQL 内容 如:.RawJoin("OUTER APPLY ( select id from t2 ) b") 原生sql语法条件,Where("id = ?id", new { id = 1 }) 提示:parms 参数还可以传 Dictionary<string, object> sql语法条件 参数 原生sql语法条件,WhereIf(true, "id = ?id", new { id = 1 }) 提示:parms 参数还可以传 Dictionary<string, object> true 时生效 sql语法条件 参数 动态过滤条件 禁用全局过滤功能,不传参数时将禁用所有 零个或多个过滤器名字 排他更新锁 注意:务必在开启事务后使用该功能 MySql: for update SqlServer: With(UpdLock, RowLock, NoWait) PostgreSQL: for update nowait Oracle: for update nowait Sqlite: 无效果 达梦: for update nowait 人大金仓: for update nowait 神通: for update noawait 按原生sql语法分组,GroupBy("concat(name, ?cc)", new { cc = 1 }) 提示:parms 参数还可以传 Dictionary<string, object> sql语法 参数 按原生sql语法聚合条件过滤,Having("count(name) = ?cc", new { cc = 1 }) 提示:parms 参数还可以传 Dictionary<string, object> sql语法条件 参数 按原生sql语法排序,OrderBy("count(name) + ?cc desc", new { cc = 1 }) 提示:parms 参数还可以传 Dictionary<string, object> sql语法 参数 按原生sql语法排序,OrderBy(true, "count(name) + ?cc desc", new { cc = 1 }) 提示:parms 参数还可以传 Dictionary<string, object> true 时生效 sql语法 参数 查询向后偏移行数 查询向后偏移行数 行数 查询多少条数据 查询多少条数据 分页 第几页 每页多少 查询数据前,去重 .Distinct().ToList(x => x.GroupName) 对指定字段去重 .Distinct().ToList() 对整个查询去重 执行SQL查询,是否有记录 lambda表达式 执行SQL查询,返回 DataTable 执行SQL查询,返回指定字段的记录,记录不存在时返回 Count 为 0 的列表 返回类型 选择列 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Count 为 0 的列表 执行SQL查询,返回指定字段的记录的第一条记录,记录不存在时返回 TReturn 默认值 返回类型 选择列 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Dto 默认值 执行SQL查询,返回指定字段的记录的第一条记录,记录不存在时返回 TReturn 默认值 返回类型 选择列 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Dto 默认值 返回即将执行的SQL语句 返回类型 选择列 字段别名 执行SQL查询,返回指定字段的聚合结果 求和 返回类型 最小值 返回类型 最大值 返回类型 平均值 返回类型 指定别名 别名 多表查询 多表查询 多表查询 多表查询 多表查询 多表查询 多表查询 多表查询 多表查询 查询条件,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表达式 多表条件查询 lambda表达式 多表条件查询 lambda表达式 多表条件查询 lambda表达式 多表条件查询 lambda表达式 多表条件查询 lambda表达式 传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 是否标识为NOT 多表查询时,该方法标记后,表达式条件将对所有表进行附加 例如:软删除、租户,每个表都给条件,挺麻烦的 fsql.Select<T1>().LeftJoin<T2>(...).Where<T2>((t1, t2 => t1.IsDeleted == false && t2.IsDeleted == false) 修改:fsql.Select<T1>().LeftJoin<T2>(...).WhereCascade(t1 => t1.IsDeleted == false) 当其中的实体可附加表达式才会进行,表越多时收益越大 按选择的列分组,GroupBy(a => a.Name) | GroupBy(a => new{a.Name,a.Time}) 按列排序,OrderBy(a => a.Time) 按列排序,OrderBy(true, a => a.Time) true 时生效 按列倒向排序,OrderByDescending(a => a.Time) 按列倒向排序,OrderByDescending(true, a => a.Time) true 时生效 贪婪加载导航属性,如果查询中已经使用了 a.Parent.Parent 类似表达式,则可以无需此操作 选择一个导航属性 贪婪加载集合的导航属性,其实是分两次查询,ToList 后进行了数据重装 文档:https://github.com/2881099/FreeSql/wiki/%e8%b4%aa%e5%a9%aa%e5%8a%a0%e8%bd%bd#%E5%AF%BC%E8%88%AA%E5%B1%9E%E6%80%A7-onetomanymanytomany 选择一个集合的导航属性,如: .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 做不到?) 实现 select .. from ( select ... from t ) a 这样的功能 使用 AsTable 方法也可以达到效果 示例:WithSql("select * from id=?id", new { id = 1 }) 提示:parms 参数还可以传 Dictionary<string, object> SQL语句 参数 查询条件,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) 按聚合条件过滤,Where(a => a.Count() > 10) lambda表达式 按列排序,OrderBy(a => a.Time) 按列倒向排序,OrderByDescending(a => a.Time) 执行SQL查询,返回指定字段的记录,记录不存在时返回 Count 为 0 的列表 返回类型 选择列 【linq to sql】专用方法,不建议直接使用 返回即将执行的SQL语句 返回类型 选择列 返回即将执行的SQL语句 指定字段 查询向后偏移行数 查询向后偏移行数 行数 查询多少条数据 查询多少条数据 分页 第几页 每页多少 查询的记录数量 查询的记录数量,以参数out形式返回 返回的变量 分组的数据 记录总数 求和 平均值 最大值 最小值 所有元素 指定事务对象 指定事务对象 不使用参数化,可通过 IFreeSql.CodeFirst.IsNotCommandParameter 全局性设置 是否不使用参数化 批量执行选项设置,一般不需要使用该方法 各数据库 rows, parameters 限制不一样,默认设置: MySql 500 3000 PostgreSQL 500 3000 SqlServer 500 2100 Oracle 200 999 Sqlite 200 999 若没有事务传入,内部(默认)会自动开启新事务,保证拆包执行的完整性。 指定根据 rows 上限数量拆分执行 指定根据 parameters 上限数量拆分执行 是否自动开启事务 批量执行时,分批次执行的进度状态 批量执行时的回调委托 更新数据,设置更新的实体 注意:实体必须定义主键,并且最终会自动附加条件 where id = source.Id 实体 更新数据,设置更新的实体集合 注意:实体必须定义主键,并且最终会自动附加条件 where id in (source.Id) 实体集合 更新数据,设置更新的实体,同时设置忽略的列 忽略 null 属性:fsql.Update<T>().SetSourceAndIgnore(item, colval => colval == null) 注意:参数 ignore 与 IUpdate.IgnoreColumns/UpdateColumns 不能同时使用 实体 属性值忽略判断, true忽略 忽略的列,IgnoreColumns(a => a.Name) | IgnoreColumns(a => new{a.Name,a.Time}) | IgnoreColumns(a => new[]{"name","time"}) 注意:不能与 UpdateColumns 不能同时使用 lambda选择列 忽略的列 注意:不能与 UpdateColumns 不能同时使用 属性名,或者字段名 指定的列,UpdateColumns(a => a.Name) | UpdateColumns(a => new{a.Name,a.Time}) | UpdateColumns(a => new[]{"name","time"}) 注意:不能与 IgnoreColumns 不能同时使用 lambda选择列 指定的列 注意:不能与 IgnoreColumns 同时使用 属性名,或者字段名 设置列的新值,Set(a => a.Name, "newvalue") lambda选择列 新值 设置列的新值,Set(a => a.Name, "newvalue") true 时生效 lambda选择列 新值 设置列的的新值为基础上增加,格式:Set(a => a.Clicks + 1) 相当于 clicks=clicks+1 指定更新,格式:Set(a => new T { Clicks = a.Clicks + 1, Time = DateTime.Now }) 相当于 set clicks=clicks+1,time='2019-06-19....' 设置列的的新值为基础上增加,格式:Set(a => a.Clicks + 1) 相当于 clicks=clicks+1 指定更新,格式:Set(a => new T { Clicks = a.Clicks + 1, Time = DateTime.Now }) 相当于 set clicks=clicks+1,time='2019-06-19....' true 时生效 设置值,自定义SQL语法,SetRaw("title = ?title", new { title = "newtitle" }) 提示:parms 参数还可以传 Dictionary<string, object> sql语法 参数 设置更新的列 SetDto(new { title = "xxx", clicks = 2 }) SetDto(new Dictionary<string, object> { ["title"] = "xxx", ["clicks"] = 2 }) 注意:标记 [Column(CanUpdate = false)] 的属性不会被更新 dto 或 Dictionary<string, object> lambda表达式条件,仅支持实体基础成员(不包含导航对象) 若想使用导航对象,请使用 ISelect.ToUpdate() 方法 lambda表达式条件 原生sql语法条件,Where("id = ?id", new { id = 1 }) 提示:parms 参数还可以传 Dictionary<string, object> sql语法条件 参数 传入实体,将主键作为条件 实体 传入实体集合,将主键作为条件 实体集合 传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 是否标识为NOT 禁用全局过滤功能,不传参数时将禁用所有 零个或多个过滤器名字 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; 动态Type,在使用 Update<object> 后使用本方法,指定实体类型 返回即将执行的SQL语句 执行SQL语句,返回影响的行数 执行SQL语句,返回更新后的记录 注意:此方法只有 Postgresql/SqlServer 有效果 主库连接池 从库连接池 数据库类型 UseConnectionString 时候的值 UseSalve 时候的值 唯一标识 开启事务(不支持异步) 事务体 () => {} 开启事务(不支持异步) 事务体 () => {} 当前线程的事务 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 查询,ExecuteReader(dr => {}, "select * from user where age > ?age", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> 查询 查询,ExecuteArray("select * from user where age > ?age", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> 查询 查询,ExecuteDataSet("select * from user where age > ?age; select 2", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> 查询 查询,ExecuteDataTable("select * from user where age > ?age", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> 在【主库】执行 在【主库】执行,ExecuteNonQuery("delete from user where age > ?age", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> 在【主库】执行 在【主库】执行,ExecuteScalar("select 1 from user where age > ?age", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> 执行SQL返回对象集合,Query<User>("select * from user where age > ?age", new SqlParameter { ParameterName = "age", Value = 25 }) 执行SQL返回对象集合,Query<User>("select * from user where age > ?age", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> 查询 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> 查询 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> 查询 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> 在【主库】执行 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> 在【主库】执行 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > ?age", new SqlParameter { ParameterName = "age", Value = 25 }) 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > ?age", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> 可自定义解析表达式 自定义实体的配置,方便和多个 ORM 共同使用 自定义实体的属性配置,方便和多个 ORM 共同使用 增删查改,执行命令之前触发 增删查改,执行命令完成后触发 CodeFirst迁移,执行之前触发 CodeFirst迁移,执行完成触发 Insert/Update自动值处理 监视数据库命令对象(执行前,调试) 监视数据库命令对象(执行后,用于监视执行性能) 跟踪开始 跟踪结束 内置解析功能,可辅助您进行解析 需要您解析的表达式 解析后的内容 实体类型 实体配置 索引配置 实体类型 实体的属性 实体的属性配置 标识符,可将 CurdBefore 与 CurdAfter 进行匹配 操作类型 实体类型 实体类型的元数据 执行的 SQL 参数化命令 发生的错误 执行SQL命令,返回的结果 耗时(单位:Ticks) 耗时(单位:毫秒) 标识符,可将 SyncStructureBeforeEventArgs 与 SyncStructureAfterEventArgs 进行匹配 实体类型 执行的 SQL 发生的错误 耗时(单位:Ticks) 耗时(单位:毫秒) 类型 属性列的元数据 反射的属性信息 获取实体的属性值,也可以设置实体的属性新值 标识符,可将 CommandBefore 与 CommandAfter 进行匹配 发生的错误 执行SQL命令,返回的结果 耗时(单位:Ticks) 耗时(单位:毫秒) 标识符,可将 TraceBeforeEventArgs 与 TraceAfterEventArgs 进行匹配 备注 发生的错误 耗时(单位: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) 不会参数化 延时加载导航属性对象,导航属性需要声明 virtual 将实体类型与数据库对比,返回DDL语句 将实体类型集合与数据库对比,返回DDL语句 实体类型 将实体类型与数据库对比,返回DDL语句(指定表名) 实体类型 指定表名对比 同步实体类型到数据库 注意:生产环境中谨慎使用 同步实体类型集合到数据库 注意:生产环境中谨慎使用 同步实体类型到数据库(指定表名) 注意:生产环境中谨慎使用 实体类型 指定表名对比 强制同步结构,无视缓存每次都同步 根据 System.Type 获取数据库信息 FreeSql FluentApi 配置实体,方法名与特性相同 FreeSql FluentApi 配置实体,方法名与特性相同 获取 FreeSql FluentApi 配置实体的元数据 未使用ConfigEntity配置时,返回null 获取实体类核心配置 获取所有数据库 获取指定数据库的表信息,包括表、列详情、主键、唯一键、索引、外键、备注 获取指定单表信息,包括列详情、主键、唯一键、索引、备注 表名,如:dbo.table1 是否忽略大小写 判断表是否存在 表名,如:dbo.table1 是否忽略大小写 获取数据库枚举类型int值 获取c#转换,(int)、(long) 获取c#值 获取c#类型,int、long 获取c#类型对象 获取ado.net读取方法, GetBoolean、GetInt64 序列化 反序列化 获取数据库枚举类型,适用 PostgreSQL 如果实体类有自增属性,分成两个 List,有值的Item1 merge,无值的Item2 insert AsType, Ctor, ClearData 三处地方需要重新加载 AsType, Ctor, ClearData 三处地方需要重新加载 动态读取 DescriptionAttribute 注释文本 通过属性的注释文本,通过 xml 读取 Dict:key=属性名,value=注释 创建一个过滤器 名字 表达式 当前操作的数据 当前批次 总批次数量 动态过滤条件 属性名:Name 导航属性:Parent.Name 多表:b.Name 操作符 Filters 下的逻辑运算符 子过滤条件,它与当前的逻辑关系是 And 注意:当前 Field 可以留空 like = Equal/Equals/Eq 效果相同 = Equal/Equals/Eq 效果相同 = Equal/Equals/Eq 效果相同 <> > >= < <= >= and < 此时 Value 的值格式为逗号分割:value1,value2 或者数组 >= and < 此时 Value 的值格式为逗号分割:date1,date2 或者数组 这是专门为日期范围查询定制的操作符,它会处理 date2 + 1,比如: 当 date2 选择的是 2020-05-30,那查询的时候是 < 2020-05-31 当 date2 选择的是 2020-05,那查询的时候是 < 2020-06 当 date2 选择的是 2020,那查询的时候是 < 2021 当 date2 选择的是 2020-05-30 12,那查询的时候是 < 2020-05-30 13 当 date2 选择的是 2020-05-30 12:30,那查询的时候是 < 2020-05-30 12:31 并且 date2 只支持以上 5 种格式 (date1 没有限制) in (1,2,3) 此时 Value 的值格式为逗号分割:value1,value2,value3... 或者数组 not in (1,2,3) 此时 Value 的值格式为逗号分割:value1,value2,value3... 或者数组 是否放弃继续读取 中间表,多对多 是否可用 不可用错误 不可用时间 将对象池设置为不可用,后续 Get/GetAsync 均会报错,同时启动后台定时检查服务恢复可用 由【可用】变成【不可用】时返回true,否则返回false 统计对象池中的对象 统计对象池中的对象(完整) 获取资源 超时 获取资源 使用完毕后,归还资源 对象 是否重新创建 名称 池容量 默认获取超时设置 空闲时间,获取时若超出,则重新创建 异步获取排队队列大小,小于等于0不生效 获取超时后,是否抛出异常 监听 AppDomain.CurrentDomain.ProcessExit/Console.CancelKeyPress 事件自动释放 后台定时检查可用性间隔秒数 对象池的对象被创建时 返回被创建的对象 销毁对象 资源对象 从对象池获取对象超时的时候触发,通过该方法统计 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 资源对象 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 资源对象 归还对象给对象池的时候触发 资源对象 检查可用性 资源对象 事件:可用时触发 事件:不可用时触发 所属对象池 在对象池中的唯一标识 资源对象 被获取的总次数 最后获取时的时间 最后归还时的时间 创建时间 最后获取时的线程id 最后归还时的线程id 重置 Value 值 对象池管理类 对象类型 后台定时检查可用性 创建对象池 池大小 池内对象的创建委托 获取池内对象成功后,进行使用前操作 创建对象池 策略 获取可用资源,或创建资源 不进行任何处理 将帕斯卡命名字符串转换为下划线分隔字符串 BigApple -> Big_Apple 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 BigApple -> BIG_APPLE 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 BigApple -> big_apple 将字符串转换为大写 BigApple -> BIGAPPLE 将字符串转换为小写 BigApple -> bigapple 不进行任何处理 将帕斯卡命名字符串转换为下划线分隔字符串 BigApple -> Big_Apple 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 BigApple -> BIG_APPLE 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 BigApple -> big_apple 将字符串转换为大写 BigApple -> BIGAPPLE 将字符串转换为小写 BigApple -> bigapple C#: that >= between && that <= and SQL: that BETWEEN between AND and 注意:这个方法和 Between 有细微区别 C#: that >= start && that < end SQL: that >= start and that < end 获取 Type 的原始 c# 文本表示 测量两个经纬度的距离,返回单位:米 经纬坐标1 经纬坐标2 返回距离(单位:米) 将 IEnumable<T> 转成 ISelect<T>,以便使用 FreeSql 的查询功能。此方法用于 Lambda 表达式中,快速进行集合导航的查询。 多表查询 多表查询 多表查询 多表查询 多表查询 多表查询 多表查询 多表查询 多表查询 本方法实现从已知的内存 List 数据,进行和 ISelect.IncludeMany 相同功能的贪婪加载 示例:new List<Song>(new[] { song1, song2, song3 }).IncludeMany(g.sqlite, a => a.Tags); 文档:https://github.com/2881099/FreeSql/wiki/%e8%b4%aa%e5%a9%aa%e5%8a%a0%e8%bd%bd#%E5%AF%BC%E8%88%AA%E5%B1%9E%E6%80%A7-onetomanymanytomany 选择一个集合的导航属性,如: .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 返回 注意:实体需要配置父子导航属性 使用递归 CTE 查询树型的所有子记录,或者所有父记录。 通过测试的数据库:MySql8.0、SqlServer、PostgreSQL、Oracle、Sqlite、达梦、人大金仓 返回隐藏字段:.ToList(a => new { item = a, level = "a.cte_level", path = "a.cte_path" }) false(默认):由父级向子级的递归查询true:由子级向父级的递归查询 路径内容选择 连接路径内容 递归层级 使用 and 拼接两个 lambda 表达式 使用 and 拼接两个 lambda 表达式 true 时生效 使用 or 拼接两个 lambda 表达式 使用 or 拼接两个 lambda 表达式 true 时生效 将 lambda 表达式取反 true 时生效 使用 and 拼接两个 lambda 表达式 使用 and 拼接两个 lambda 表达式 true 时生效 使用 or 拼接两个 lambda 表达式 使用 or 拼接两个 lambda 表达式 true 时生效 将 lambda 表达式取反 true 时生效 使用 and 拼接两个 lambda 表达式 使用 and 拼接两个 lambda 表达式 true 时生效 使用 or 拼接两个 lambda 表达式 使用 or 拼接两个 lambda 表达式 true 时生效 将 lambda 表达式取反 true 时生效 使用 and 拼接两个 lambda 表达式 使用 and 拼接两个 lambda 表达式 true 时生效 使用 or 拼接两个 lambda 表达式 使用 or 拼接两个 lambda 表达式 true 时生效 将 lambda 表达式取反 true 时生效 使用 and 拼接两个 lambda 表达式 使用 and 拼接两个 lambda 表达式 true 时生效 使用 or 拼接两个 lambda 表达式 使用 or 拼接两个 lambda 表达式 true 时生效 将 lambda 表达式取反 true 时生效 生成类似Mongodb的ObjectId有序、不重复Guid 插入数据 插入数据,传入实体 插入数据,传入实体数组 插入数据,传入实体集合 插入数据,传入实体集合 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: 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 方法(不依赖数据库特性) 修改数据 修改数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 查询数据 查询数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 删除数据 删除数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 开启事务(不支持异步) v1.5.0 关闭了线程事务超时自动提交的机制 事务体 () => {} 开启事务(不支持异步) v1.5.0 关闭了线程事务超时自动提交的机制 事务体 () => {} 数据库访问对象 所有拦截方法都在这里 CodeFirst 模式开发相关方法 DbFirst 模式开发相关方法 全局过滤设置,可默认附加为 Select/Update/Delete 条件