diff --git a/更新日志.md b/更新日志.md index 817cf4e..17e3426 100644 --- a/更新日志.md +++ b/更新日志.md @@ -1,7 +1,12 @@ 完整版本:年数-月-日-当日版本号,FreeSql、FreeSql.Repository、FreeSql.DbContext 版本号相同。 -## v0.11.24 +## v0.12.1 + +- 增加 ICodeFirst.IsGenerateCommandParameterWithLambda 选项,开启表达式解析的命令参数化; +> FreeSqlBuilder 上使用 UseGenerateCommandParameterWithLambda(true) 开启 +- 增加 ExpressionCallContext 自定义函数上下文档 DbParameter 属性; +- 修复 IncludeMany(a => a.x1.x2.Childs) 当 x1, x2 为 null 的报 null 错误; - 增加 Repository/DbContext SaveMany 方法实现一对多,子数据的完整保存; - 调整 SaveManyToMany 方法名为 SaveMany; diff --git a/表达式函数.md b/表达式函数.md index 7edc49a..ec84508 100644 --- a/表达式函数.md +++ b/表达式函数.md @@ -80,6 +80,60 @@ context.Value.DataType 是 FreeSql.DataType 枚举类型,以便实现不同数 context.Value.Values 是 函数的各参数解析结果; +## 命令参数化(v0.12.1) + +在之前 Where(lambda) 解析出来的是纯文本,做了防止注入功能,对数据库执行计划要求高的,现在可以开启 lambda 参数化功能。 + +```csharp +var fsql = new FreeSqlBuilder() + .UseGenerateCommandParameterWithLambda(true) + ... + +var id = 1; +fsql.Select().Where(a => a.Id == id).ToList(); +//SELECT .. FROM `Song` a WHERE `Id` = ?exp_0 +``` + +生成的参数对象,DbType、Size、Precision、Scale 设置默认已作优化,与实体属性一致。 + +诡异操作: + +> 如果不希望 string 参数与实体属性的 Size 相同,可利用自定义表达式函数功能,如下: + +```csharp +var name = "testname"; +fsql.Select() + .Where(a => a.varchar == name).ToList(); + +fsql.Select() + .Where(a => a.varchar == name.SetDbParameter(10)).ToList(); + +public class TestMySqlStringIsNullable +{ + public Guid id { get; set; } + + [Column(DbType = "varchar(100)")] + public string varchar { get; set; } +} + +[ExpressionCall] +public static class DbFunc +{ + static ThreadLocal context = new ThreadLocal(); + + public static string SetDbParameter(this string that, int size) + { + if (context.Value.DbParameter != null) + context.Value.DbParameter.Size = size; + return context.Value.Values["that"]; + } +} +``` + +第一条语句产生的参数对象 Size 为 100,第二条为 10: + +![image](https://user-images.githubusercontent.com/16286519/69433211-2c5fcf80-0d76-11ea-8eec-963eb37199c5.png) + ## AOP拦截解析 IFreeSql 对象有 Aop 成员,那里提供一堆 AOP 拦截的方法。其实有一个事件名称:ParseExpression。