From d67e9644ebe1a7f7aa60001d29abdc51c6682475 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 4 Jan 2020 22:53:39 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20=E5=8F=82=E8=80=83=20C?= =?UTF-8?q?hloe=20=E8=A1=A8=E8=BE=BE=E5=BC=8F=E9=92=88=E5=AF=B9=E5=8F=98?= =?UTF-8?q?=E9=87=8F=E7=9A=84=E8=A7=A3=E6=9E=90=EF=BC=8C=E6=8F=90=E5=8D=87?= =?UTF-8?q?=E4=BA=86=E4=B8=80=E5=80=8D=E6=80=A7=E8=83=BD=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 + FreeSql/FreeSql.xml | 361 +++++++++++++----------- FreeSql/Internal/CommonExpression.cs | 32 ++- 3 files changed, 230 insertions(+), 170 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index dc0203b8..d9f91124 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index e4bdedbe..59e0a2ec 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2430,7 +2430,178 @@ 内置解析功能,可辅助您进行解析 - mmary> + + + + 需要您解析的表达式 + + + + + 解析后的内容 + + + + + 实体类型 + + + + + 实体配置 + + + + + 索引配置 + + + + + 实体类型 + + + + + 实体的属性 + + + + + 实体的属性配置 + + + + + 标识符,可将 CurdBefore 与 CurdAfter 进行匹配 + + + + + 操作类型 + + + + + 实体类型 + + + + + 实体类型的元数据 + + + + + 执行的 SQL + + + + + 参数化命令 + + + + + 发生的错误 + + + + + 执行SQL命令,返回的结果 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 标识符,可将 SyncStructureBeforeEventArgs 与 SyncStructureAfterEventArgs 进行匹配 + + + + + 实体类型 + + + + + 执行的 SQL + + + + + 发生的错误 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 类型 + + + + + 属性列的元数据 + + + + + 反射的属性信息 + + + + + 获取实体的属性值,也可以设置实体的属性新值 + + + + + 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 + + + + + 转小写同步结构 + + + + + 转大写同步结构 + + + + + 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 + 本功能会影响 IFreeSql 首次访问的速度。 + 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 + + + + + 不使用命令参数化执行,针对 Insert/Update + + + + + 是否生成命令参数化执行,针对 lambda 表达式解析 + @@ -2716,189 +2887,41 @@ C#:从元组集合中查找 exp1, exp2, exp2 是否存在 SQL: exp1 = that[0].Item1 and exp2 = that[0].Item2 and exp3 = that[0].Item3 OR - exp1 = that[1].Item1 and exp2 = that[1].Item2 aummary> - 获取ado.net读取方法, GetBoolean、GetInt64 + exp1 = that[1].Item1 and exp2 = that[1].Item2 and exp3 = that[1].Item3 OR + ... + 注意:当 that 为 null 或 empty 时,返回 1=0 - + + + + + + + - + - 序列化 + 测量两个经纬度的距离,返回单位:米 - - + 经纬坐标1 + 经纬坐标2 + 返回距离(单位:米) - + - 反序列化 - - - - - - - 获取数据库枚举类型,适用 PostgreSQL - - - - - - - AsType, Ctor, ClearData 三处地方需要重新加载 - - - - - AsType, Ctor, ClearData 三处地方需要重新加载 - - - - - 通过属性的注释文本,通过 xml 读取 - - - Dict:key=属性名,value=注释 - - - - 创建一个过滤器 + 将 IEnumable<T> 转成 ISelect<T>,以便使用 FreeSql 的查询功能。此方法用于 Lambad 表达式中,快速进行集合导航的查询。 - 名字 - 表达式 + - + - 中间表,多对多 - - - - - 不进行任何处理 - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串 - - BigApple -> Big_Apple - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 - - BigApple -> BIG_APPLE - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 - - BigApple -> big_apple - - - - - 将字符串转换为大写 - - BigApple -> BIGAPPLE - - - - - 将字符串转换为小写 - - BigApple -> bigapple - - - - - 将帕斯系映射,如: .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 做不到?) - - - - - 使用 and 拼接两个 lambda 表达式 + 多表查询 - - - 使用 and 拼接两个 lambda 表达式 - - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - er> 多表查询 diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index a6beb913..0765d7d4 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -1005,6 +1005,7 @@ namespace FreeSql.Internal if (string.IsNullOrEmpty(other4Exp) == false) return other4Exp; } var expStack = new Stack(); + var expStackConstOrMemberCount = 1; expStack.Push(exp); MethodCallExpression callExp = null; var exp2 = exp4?.Expression; @@ -1014,6 +1015,7 @@ namespace FreeSql.Internal { case ExpressionType.Constant: expStack.Push(exp2); + expStackConstOrMemberCount++; break; case ExpressionType.Parameter: expStack.Push(exp2); @@ -1021,6 +1023,7 @@ namespace FreeSql.Internal case ExpressionType.MemberAccess: expStack.Push(exp2); exp2 = (exp2 as MemberExpression).Expression; + expStackConstOrMemberCount++; if (exp2 == null) break; continue; case ExpressionType.Call: @@ -1043,7 +1046,34 @@ namespace FreeSql.Internal } break; } - if (expStack.First().NodeType != ExpressionType.Parameter) return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp, tsc.dbParams); + if (expStack.First().NodeType != ExpressionType.Parameter) + { + if (expStackConstOrMemberCount == expStack.Count) + { + object firstValue = null; + switch (expStack.First().NodeType) + { + case ExpressionType.Constant: + var expStackFirst = expStack.Pop() as ConstantExpression; + firstValue = expStackFirst?.Value; + break; + case ExpressionType.MemberAccess: + var expStackFirstMem = expStack.First() as MemberExpression; + if (expStackFirstMem.Expression?.NodeType == ExpressionType.Constant) firstValue = (expStackFirstMem.Expression as ConstantExpression)?.Value; + break; + } + while (expStack.Any()) + { + var expStackItem = expStack.Pop() as MemberExpression; + if (expStackItem.Member.MemberType == MemberTypes.Property) + firstValue = ((PropertyInfo)expStackItem.Member).GetValue(firstValue, null); + else if (expStackItem.Member.MemberType == MemberTypes.Field) + firstValue = ((FieldInfo)expStackItem.Member).GetValue(firstValue); + } + return formatSql(firstValue, tsc.mapType, tsc.mapColumnTmp, tsc.dbParams); + } + return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp, tsc.dbParams); + } if (callExp != null) return ExpressionLambdaToSql(callExp, tsc); if (tsc.getSelectGroupingMapString != null && expStack.First().Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) {