diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs index a381b2fa..b3ee6661 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs @@ -725,15 +725,15 @@ namespace FreeSql.Tests.Odbc.Default [Fact] public void Sum() { - var subquery = select.ToSql(a => new + var subquery = select.Where(a => a.Id < 200).ToSql(a => new { all = a, - count = select.Sum(b => b.Id) + count = select.Where(b => b.Id < 200).Sum(b => b.Id) }); - var subqueryList = select.ToList(a => new + var subqueryList = select.Where(a => a.Id < 200).ToList(a => new { all = a, - count = select.Sum(b => b.Id) + count = select.Where(b => b.Id < 200).Sum(b => b.Id) }); } [Fact] @@ -767,15 +767,15 @@ namespace FreeSql.Tests.Odbc.Default [Fact] public void Avg() { - var subquery = select.ToSql(a => new + var subquery = select.Where(a => a.Id < 200).ToSql(a => new { all = a, - count = select.Avg(b => b.Id) + count = select.Where(b => b.Id < 200).Sum(b => b.Id) }); - var subqueryList = select.ToList(a => new + var subqueryList = select.Where(a => a.Id < 200).ToList(a => new { all = a, - count = select.Avg(b => b.Id) + count = select.Where(b => b.Id < 200).Sum(b => b.Id) }); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/MapType/BoolNullableTest.cs index b13d90e9..ec8f5d6a 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/MapType/BoolNullableTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/MapType/BoolNullableTest.cs @@ -1567,30 +1567,5 @@ namespace FreeSql.Tests.Odbc.DefaultMapType public void GuidNullable() { } - - [Fact] - public void MygisPoint() - { - } - [Fact] - public void MygisLineString() - { - } - [Fact] - public void MygisPolygon() - { - } - [Fact] - public void MygisMultiPoint() - { - } - [Fact] - public void MygisMultiLineString() - { - } - [Fact] - public void MygisMultiPolygon() - { - } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/MapType/BoolTest.cs index cf68b373..544aca1d 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/MapType/BoolTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/MapType/BoolTest.cs @@ -1100,30 +1100,5 @@ namespace FreeSql.Tests.Odbc.DefaultMapType public void GuidNullable() { } - - [Fact] - public void MygisPoint() - { - } - [Fact] - public void MygisLineString() - { - } - [Fact] - public void MygisPolygon() - { - } - [Fact] - public void MygisMultiPoint() - { - } - [Fact] - public void MygisMultiLineString() - { - } - [Fact] - public void MygisMultiPolygon() - { - } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/BoolNullableTest.cs index e2c5c4ee..e6f685a6 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/BoolNullableTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/BoolNullableTest.cs @@ -1567,30 +1567,5 @@ namespace FreeSql.Tests.Odbc.OracleMapType public void GuidNullable() { } - - [Fact] - public void MygisPoint() - { - } - [Fact] - public void MygisLineString() - { - } - [Fact] - public void MygisPolygon() - { - } - [Fact] - public void MygisMultiPoint() - { - } - [Fact] - public void MygisMultiLineString() - { - } - [Fact] - public void MygisMultiPolygon() - { - } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/BoolTest.cs index decd881f..54ee44e8 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/BoolTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/BoolTest.cs @@ -1101,30 +1101,5 @@ namespace FreeSql.Tests.Odbc.OracleMapType public void GuidNullable() { } - - [Fact] - public void MygisPoint() - { - } - [Fact] - public void MygisLineString() - { - } - [Fact] - public void MygisPolygon() - { - } - [Fact] - public void MygisMultiPoint() - { - } - [Fact] - public void MygisMultiLineString() - { - } - [Fact] - public void MygisMultiPolygon() - { - } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/BoolNullableTest.cs index 0c8c0d7f..c9e0dcce 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/BoolNullableTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/BoolNullableTest.cs @@ -1567,30 +1567,5 @@ namespace FreeSql.Tests.Odbc.PostgreSQLMapType public void GuidNullable() { } - - [Fact] - public void MygisPoint() - { - } - [Fact] - public void MygisLineString() - { - } - [Fact] - public void MygisPolygon() - { - } - [Fact] - public void MygisMultiPoint() - { - } - [Fact] - public void MygisMultiLineString() - { - } - [Fact] - public void MygisMultiPolygon() - { - } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/BoolTest.cs index a91a204f..b88d79a9 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/BoolTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/BoolTest.cs @@ -1101,30 +1101,5 @@ namespace FreeSql.Tests.Odbc.PostgreSQLMapType public void GuidNullable() { } - - [Fact] - public void MygisPoint() - { - } - [Fact] - public void MygisLineString() - { - } - [Fact] - public void MygisPolygon() - { - } - [Fact] - public void MygisMultiPoint() - { - } - [Fact] - public void MygisMultiLineString() - { - } - [Fact] - public void MygisMultiPolygon() - { - } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs index 0174b4aa..d604deeb 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs @@ -706,15 +706,15 @@ namespace FreeSql.Tests.Odbc.SqlServer [Fact] public void Sum() { - var subquery = select.ToSql(a => new + var subquery = select.Where(a => a.Id < 200).ToSql(a => new { all = a, - count = select.Sum(b => b.Id) + count = select.Where(b => b.Id < 200).Sum(b => b.Id) }); - var subqueryList = select.ToList(a => new + var subqueryList = select.Where(a => a.Id < 200).ToList(a => new { all = a, - count = select.Sum(b => b.Id) + count = select.Where(b => b.Id < 200).Sum(b => b.Id) }); } [Fact] @@ -748,15 +748,15 @@ namespace FreeSql.Tests.Odbc.SqlServer [Fact] public void Avg() { - var subquery = select.ToSql(a => new + var subquery = select.Where(a => a.Id < 100).ToSql(a => new { all = a, - count = select.Avg(b => b.Id) + count = select.Where(b => b.Id < 100).Avg(b => b.Id) }); - var subqueryList = select.ToList(a => new + var subqueryList = select.Where(a => a.Id < 100).ToList(a => new { all = a, - count = select.Avg(b => b.Id) + count = select.Where(b => b.Id < 100).Avg(b => b.Id) }); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/BoolNullableTest.cs index 328f733b..ee59233e 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/BoolNullableTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/BoolNullableTest.cs @@ -1568,30 +1568,5 @@ namespace FreeSql.Tests.Odbc.SqlServerMapType public void GuidNullable() { } - - [Fact] - public void MygisPoint() - { - } - [Fact] - public void MygisLineString() - { - } - [Fact] - public void MygisPolygon() - { - } - [Fact] - public void MygisMultiPoint() - { - } - [Fact] - public void MygisMultiLineString() - { - } - [Fact] - public void MygisMultiPolygon() - { - } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/BoolTest.cs index b7ec3e4e..5d152b19 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/BoolTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/BoolTest.cs @@ -1101,30 +1101,5 @@ namespace FreeSql.Tests.Odbc.SqlServerMapType public void GuidNullable() { } - - [Fact] - public void MygisPoint() - { - } - [Fact] - public void MygisLineString() - { - } - [Fact] - public void MygisPolygon() - { - } - [Fact] - public void MygisMultiPoint() - { - } - [Fact] - public void MygisMultiLineString() - { - } - [Fact] - public void MygisMultiPolygon() - { - } } } diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml index 6e6ec049..d0b42783 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml @@ -204,6 +204,14 @@ 回复的文本内容 + + + 设置表达式中的 string 参数化长度,优化执行计划 + + + + + 调价单 diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/BoolNullableTest.cs index d3da1a49..0224c6c5 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/BoolNullableTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/BoolNullableTest.cs @@ -1567,30 +1567,5 @@ namespace FreeSql.Tests.OracleMapType public void GuidNullable() { } - - [Fact] - public void MygisPoint() - { - } - [Fact] - public void MygisLineString() - { - } - [Fact] - public void MygisPolygon() - { - } - [Fact] - public void MygisMultiPoint() - { - } - [Fact] - public void MygisMultiLineString() - { - } - [Fact] - public void MygisMultiPolygon() - { - } } } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/BoolTest.cs index 0aab5f9f..d0dd9c37 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/BoolTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/BoolTest.cs @@ -1101,30 +1101,5 @@ namespace FreeSql.Tests.OracleMapType public void GuidNullable() { } - - [Fact] - public void MygisPoint() - { - } - [Fact] - public void MygisLineString() - { - } - [Fact] - public void MygisPolygon() - { - } - [Fact] - public void MygisMultiPoint() - { - } - [Fact] - public void MygisMultiLineString() - { - } - [Fact] - public void MygisMultiPolygon() - { - } } } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/BoolNullableTest.cs index 73804ba1..2a5038d9 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/BoolNullableTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/BoolNullableTest.cs @@ -1567,30 +1567,5 @@ namespace FreeSql.Tests.PostgreSQLMapType public void GuidNullable() { } - - [Fact] - public void MygisPoint() - { - } - [Fact] - public void MygisLineString() - { - } - [Fact] - public void MygisPolygon() - { - } - [Fact] - public void MygisMultiPoint() - { - } - [Fact] - public void MygisMultiLineString() - { - } - [Fact] - public void MygisMultiPolygon() - { - } } } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/BoolTest.cs index 37ce2ca4..574facca 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/BoolTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/BoolTest.cs @@ -1101,30 +1101,5 @@ namespace FreeSql.Tests.PostgreSQLMapType public void GuidNullable() { } - - [Fact] - public void MygisPoint() - { - } - [Fact] - public void MygisLineString() - { - } - [Fact] - public void MygisPolygon() - { - } - [Fact] - public void MygisMultiPoint() - { - } - [Fact] - public void MygisMultiLineString() - { - } - [Fact] - public void MygisMultiPolygon() - { - } } } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolNullableTest.cs index ad683985..86552fc1 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolNullableTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolNullableTest.cs @@ -1577,30 +1577,5 @@ namespace FreeSql.Tests.SqlServerMapType public void GuidNullable() { } - - [Fact] - public void MygisPoint() - { - } - [Fact] - public void MygisLineString() - { - } - [Fact] - public void MygisPolygon() - { - } - [Fact] - public void MygisMultiPoint() - { - } - [Fact] - public void MygisMultiLineString() - { - } - [Fact] - public void MygisMultiPolygon() - { - } } } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolTest.cs index 9d3e5d46..7c5ab8ff 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolTest.cs @@ -1110,30 +1110,5 @@ namespace FreeSql.Tests.SqlServerMapType public void GuidNullable() { } - - [Fact] - public void MygisPoint() - { - } - [Fact] - public void MygisLineString() - { - } - [Fact] - public void MygisPolygon() - { - } - [Fact] - public void MygisMultiPoint() - { - } - [Fact] - public void MygisMultiLineString() - { - } - [Fact] - public void MygisMultiPolygon() - { - } } } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/BoolNullableTest.cs index 1d261272..78d46bd2 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/BoolNullableTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/BoolNullableTest.cs @@ -1567,30 +1567,5 @@ namespace FreeSql.Tests.SqliteMapType public void GuidNullable() { } - - [Fact] - public void MygisPoint() - { - } - [Fact] - public void MygisLineString() - { - } - [Fact] - public void MygisPolygon() - { - } - [Fact] - public void MygisMultiPoint() - { - } - [Fact] - public void MygisMultiLineString() - { - } - [Fact] - public void MygisMultiPolygon() - { - } } } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/BoolTest.cs index 846817f5..367910bd 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/BoolTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/BoolTest.cs @@ -1101,30 +1101,5 @@ namespace FreeSql.Tests.SqliteMapType public void GuidNullable() { } - - [Fact] - public void MygisPoint() - { - } - [Fact] - public void MygisLineString() - { - } - [Fact] - public void MygisPolygon() - { - } - [Fact] - public void MygisMultiPoint() - { - } - [Fact] - public void MygisMultiLineString() - { - } - [Fact] - public void MygisMultiPolygon() - { - } } } diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index 97b4b8d1..1f809d0f 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -185,8 +185,6 @@ namespace FreeSql.Tests [Fact] public void Test02() { - var testparmSelect = g.sqlserver.Select().Where(a => a.nvarchar == "11" && a.nvarchar_notnull == "22" && a.nvarchar_null == "33" && a.varchar == "11" && a.varchar_notnull == "22" && a.varchar_null == "33"); - var slsksd = g.mysql.Update().SetSource(new UserLike { Id = Guid.NewGuid(), CreateUserId = 1000, SubjectId = Guid.NewGuid() }) .UpdateColumns(a => new { @@ -291,6 +289,57 @@ namespace FreeSql.Tests var sql = g.sqlite.Select() .ToSql(a => a.CreateTime.FormatDateTime("yyyy-MM-dd")); + + + var parm1 = "11"; + var parm2 = "22"; + var parm3 = "33"; + var testparmSelect = g.sqlserver.Select() + .Where(a => + a.nvarchar == "11" && + a.nvarchar_notnull == "22" && + a.nvarchar_null == "33" && + a.varchar == "11" && + a.varchar_notnull == "22" && + a.varchar_null == "33" && + + a.nvarchar == parm1 && + a.nvarchar_notnull == parm2 && + a.nvarchar_null == parm3 && + a.varchar == parm3 && + a.varchar_notnull == parm2 && + a.varchar_null == parm3 && + + a.nvarchar == parm1.SetDbParameter(10) && + a.nvarchar_notnull == parm2.SetDbParameter(11) && + a.nvarchar_null == parm3.SetDbParameter(12) && + a.varchar == parm3.SetDbParameter(13) && + a.varchar_notnull == parm2.SetDbParameter(14) && + a.varchar_null == parm3.SetDbParameter(15) && + + + "11" == a.nvarchar && + "22" == a.nvarchar_notnull && + "33" == a.nvarchar_null && + "11" == a.varchar && + "22" == a.varchar_notnull && + "33" == a.varchar_null && + + parm1 == a.nvarchar && + parm2 == a.nvarchar_notnull && + parm3 == a.nvarchar_null && + parm1 == a.varchar && + parm2 == a.varchar_notnull && + parm3 == a.varchar_null && + + parm1.SetDbParameter(10) == a.nvarchar && + parm2.SetDbParameter(11) == a.nvarchar_notnull && + parm3.SetDbParameter(12) == a.nvarchar_null && + parm1.SetDbParameter(13) == a.varchar && + parm2.SetDbParameter(14) == a.varchar_notnull && + parm3.SetDbParameter(15) == a.varchar_null + + ); } } @@ -301,7 +350,20 @@ namespace FreeSql.Tests public static string FormatDateTime(this DateTime that, string arg1) { - return $"date_format({context.Value.Values["arg1"]})"; + return $"date_format({context.Value.Values["that"]}, {context.Value.Values["arg1"]})"; + } + + /// + /// 设置表达式中的 string 参数化长度,优化执行计划 + /// + /// + /// + /// + public static string SetDbParameter(this string that, int size) + { + if (context.Value.DbParameter != null) + context.Value.DbParameter.Size = size; + return context.Value.Values["that"]; } } } diff --git a/FreeSql/DataAnnotations/ExpressionCallAttribute.cs b/FreeSql/DataAnnotations/ExpressionCallAttribute.cs index 4cd22f54..3c27b078 100644 --- a/FreeSql/DataAnnotations/ExpressionCallAttribute.cs +++ b/FreeSql/DataAnnotations/ExpressionCallAttribute.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Data.Common; using System.Text; namespace FreeSql.DataAnnotations @@ -18,11 +19,16 @@ namespace FreeSql.DataAnnotations /// /// 数据库类型,可用于适配多种数据库环境 /// - public DataType DataType { get; set; } + public DataType DataType { get; internal set; } /// /// 已解析的表达式中参数内容 /// public Dictionary Values { get; } = new Dictionary(); + + /// + /// 主对象的参数化对象,可重塑其属性 + /// + public DbParameter DbParameter { get; internal set; } } } diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 1bea2b5d..9a2604b7 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -128,16 +128,9 @@ public static partial class FreeSqlGlobalExtensions /// /// /// - public static ISelect AsSelect(this IEnumerable that) where TEntity : class - { - throw new NotImplementedException(); - } - public static ISelect AsSelect(this IEnumerable that, IFreeSql orm = null) where TEntity : class - { - return orm?.Select(); - } - - public static FreeSql.ISelect Queryable(this IFreeSql freesql) where T : class => freesql.Select(); + public static ISelect AsSelect(this IEnumerable that) where TEntity : class => throw new NotImplementedException(); + public static ISelect AsSelect(this IEnumerable that, IFreeSql orm = null) where TEntity : class => orm?.Select(); + public static ISelect Queryable(this IFreeSql freesql) where T : class => freesql.Select(); #region 多表查询 /// diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 56b67dc0..dbe7beb2 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -168,6 +168,11 @@ 已解析的表达式中参数内容 + + + 主对象的参数化对象,可重塑其属性 + + 索引名 @@ -587,6 +592,13 @@ + + + 是否生成命令参数化执行,针对 lambda 表达式解析 + + + + 延时加载导航属性对象,导航属性需要声明 virtual @@ -2282,156 +2294,7 @@ - 耗时(单位:毫秒) - - - - - 标识符,可将 SyncStructureBeforeEventArgs 与 SyncStructureAfterEventArgs 进行匹配 - - - - - 实体类型 - - - - - 执行的 SQL - - - - - 发生的错误 - - - - - 耗时(单位:Ticks) - - - - - 耗时(单位:毫秒) - - - - - 类型 - - - - - 属性列的元数据 - - - - - 反射的属性信息 - - - - - 获取实体的属性值,也可以设置实体的属性新值 - - - - - 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 - - - - - 转小写同步结构 - - - - - 转大写同步结构 - - - - - 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 - 本功能会影响 IFreeSql 首次访问的速度。 - 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 - - - - - 不使用命令参数化执行,针对 Insert/Update - - - - - 延时加载导航属性对象,导航属性需要声明 virtual - - - - - 将实体类型与数据库对比,返回DDL语句 - - - - - - - 将实体类型集合与数据库对比,返回DDL语句 - - 实体类型 - - - - - 将实体类型与数据库对比,返回DDL语句(指定表名) - - 实体类型 - 指定表名对比 - - - - - 同步实体类型到数据库 - - - - - - - 同步实体类型集合到数据库 - - - - - - - 同步实体类型到数据库(指定表名) - - 实体类型 - 指定表名对比 - - - - - 根据 System.Type 获取数据库信息 - - - - - - - 在外部配置实体的特性 - - - - - - - - 在外部配置实体的特性 - - - + 耗时(单位:毫秒 @@ -2626,6 +2489,165 @@ + + + 多表查询 + + + + + + + + 获取c#值 + + + + + + + 获取c#类型,int、long + + + + + + + 获取c#类型对象 + + + + + + + 获取ado.net读取方法, GetBoolean、GetInt64 + + + + + + + 序列化 + + + + + + + 反序列化 + + + + + + + 获取数据库枚举类型,适用 PostgreSQL + + + + + + + AsType, Ctor, ClearData 三处地方需要重新加载 + + + + + AsType, Ctor, ClearData 三处地方需要重新加载 + + + + + 通过属性的注释文本,通过 xml 读取 + + + Dict:key=属性名,value=注释 + + + + 创建一个过滤器 + + + 名字 + 表达式 + + + + + 中间表,多对多 + + + + + 不进行任何处理 + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串 + + BigApple -> Big_Apple + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 + + BigApple -> BIG_APPLE + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 + + BigApple -> big_apple + + + + + 将字符串转换为大写 + + BigApple -> BIGAPPLE + + + + + 将字符串转换为小写 + + BigApple -> bigapple + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串 + + BigApple -> Big_Apple + + + + + + + 测量两个经纬度的距离,返回单位:米 + + 经纬坐标1 + 经纬坐标2 + 返回距离(单位:米) + + + + 将 IEnumable<T> 转成 ISelect<T>,以便使用 FreeSql 的查询功能。此方法用于 Lambad 表达式中,快速进行集合导航的查询。 + + + + + + + + 多表查询 + + + 多表查询 diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index f7e979ca..fb754ac8 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -17,6 +17,7 @@ namespace FreeSql bool _isSyncStructureToUpper = false; bool _isConfigEntityFromDbFirst = false; bool _isNoneCommandParameter = false; + bool _isGenerateCommandParameterWithLambda = false; bool _isLazyLoading = false; StringConvertType _entityPropertyConvertType = StringConvertType.None; Action _aopCommandExecuting = null; @@ -100,6 +101,16 @@ namespace FreeSql return this; } /// + /// 是否生成命令参数化执行,针对 lambda 表达式解析 + /// + /// + /// + public FreeSqlBuilder UseGenerateCommandParameterWithLambda(bool value) + { + _isGenerateCommandParameterWithLambda = value; + return this; + } + /// /// 延时加载导航属性对象,导航属性需要声明 virtual /// /// diff --git a/FreeSql/Interface/ICodeFirst.cs b/FreeSql/Interface/ICodeFirst.cs index e79fe7cc..2d1cec92 100644 --- a/FreeSql/Interface/ICodeFirst.cs +++ b/FreeSql/Interface/ICodeFirst.cs @@ -31,6 +31,10 @@ namespace FreeSql /// bool IsNoneCommandParameter { get; set; } /// + /// 是否生成命令参数化执行,针对 lambda 表达式解析 + /// + bool IsGenerateCommandParameterWithLambda { get; set; } + /// /// 延时加载导航属性对象,导航属性需要声明 virtual /// bool IsLazyLoading { get; set; } diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 3bb464b3..6cc728e0 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -423,13 +423,14 @@ namespace FreeSql.Internal return $"({ExpressionLambdaToSql(leftExp, tsc)} {oper} {ExpressionLambdaToSql(rightExp, tsc)})"; } + Type oldMapType = null; var left = ExpressionLambdaToSql(leftExp, tsc); var leftMapColumn = SearchColumnByField(tsc._tables, tsc.currentTable, left); var isLeftMapType = leftMapColumn != null && new[] { "AND", "OR" }.Contains(oper) == false && (leftMapColumn.Attribute.MapType != rightExp.Type || leftMapColumn.CsType != rightExp.Type); ColumnInfo rightMapColumn = null; var isRightMapType = false; - if (isLeftMapType) tsc.mapType = leftMapColumn.Attribute.MapType; - + if (isLeftMapType) oldMapType = tsc.SetMapTypeReturnOld(leftMapColumn.Attribute.MapType); + var right = ExpressionLambdaToSql(rightExp, tsc); if (right != "NULL" && isLeftMapType) { @@ -443,7 +444,7 @@ namespace FreeSql.Internal isRightMapType = rightMapColumn != null && new[] { "AND", "OR" }.Contains(oper) == false && (rightMapColumn.Attribute.MapType != leftExp.Type || rightMapColumn.CsType != leftExp.Type); if (isRightMapType) { - tsc.mapType = rightMapColumn.Attribute.MapType; + oldMapType = tsc.SetMapTypeReturnOld(rightMapColumn.Attribute.MapType); left = ExpressionLambdaToSql(leftExp, tsc); if (left != "NULL" && isRightMapType) { @@ -495,7 +496,7 @@ namespace FreeSql.Internal else right = GetBoolString(right); break; } - tsc.mapType = null; + tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); return $"{left} {oper} {right}"; } static ConcurrentDictionary _dicTypeExistsExpressionCallAttribute = new ConcurrentDictionary(); @@ -532,7 +533,7 @@ namespace FreeSql.Internal return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc); case ExpressionType.Negate: case ExpressionType.NegateChecked: return "-" + ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc); - case ExpressionType.Constant: return formatSql((exp as ConstantExpression)?.Value, tsc.mapType, tsc.mapColumnTmp, tsc.dbParams); + case ExpressionType.Constant: return formatSql((exp as ConstantExpression)?.Value, tsc.mapType, tsc.mapColumnTmp, null); case ExpressionType.Conditional: var condExp = exp as ConditionalExpression; return $"case when {ExpressionLambdaToSql(condExp.Test, tsc)} then {ExpressionLambdaToSql(condExp.IfTrue, tsc)} else {ExpressionLambdaToSql(condExp.IfFalse, tsc)} end"; @@ -543,15 +544,21 @@ namespace FreeSql.Internal { var ecc = new ExpressionCallContext { DataType = _ado.DataType }; var exp3MethodParams = exp3.Method.GetParameters(); - for (var a = 0; a < exp3.Arguments.Count; a++) + var dbParamsIndex = tsc.dbParams?.Count; + ecc.Values.Add(exp3MethodParams[0].Name, ExpressionLambdaToSql(exp3.Arguments[0], tsc)); + if (tsc.dbParams?.Count > dbParamsIndex) ecc.DbParameter = tsc.dbParams.Last(); + List oldDbParams = tsc.dbParams; + tsc.dbParams = null; + for (var a = 1; a < exp3.Arguments.Count; a++) if (exp3.Arguments[a].Type != typeof(ExpressionCallContext)) ecc.Values.Add(exp3MethodParams[a].Name, ExpressionLambdaToSql(exp3.Arguments[a], tsc)); + tsc.dbParams = oldDbParams; var exp3InvokeParams = new object[exp3.Arguments.Count]; for (var a = 0; a < exp3.Arguments.Count; a++) { if (exp3.Arguments[a].Type != typeof(ExpressionCallContext)) - exp3InvokeParams[a] = exp3.Arguments[a].Type.CreateInstanceGetDefaultValue(); + exp3InvokeParams[a] = Utils.GetDataReaderValue(exp3.Arguments[a].Type, ecc.Values[exp3MethodParams[a].Name]);// exp3.Arguments[a].Type.CreateInstanceGetDefaultValue(); else exp3InvokeParams[a] = ecc; } @@ -1321,13 +1328,13 @@ namespace FreeSql.Internal public string formatSql(object obj, Type mapType, ColumnInfo mapColumn, List dbParams) { //参数化设置,日后优化 - //if (dbParams != null && mapColumn != null) - //{ - // var paramName = $"exp_{dbParams.Count}"; - // var parm = _common.AppendParamter(dbParams, paramName, mapColumn, mapType ?? mapColumn.Attribute.MapType, mapType == null ? obj : Utils.GetDataReaderValue(mapType, obj)); - // _common.SetParameterSize(parm, mapColumn.Attribute.DbType, mapColumn); - // return _common.QuoteParamterName(paramName); - //} + if (dbParams != null) + { + var paramName = $"exp_{dbParams.Count}"; + var parm = _common.AppendParamter(dbParams, paramName, mapColumn, + mapType ?? mapColumn?.Attribute.MapType ?? obj?.GetType(), mapType == null ? obj : Utils.GetDataReaderValue(mapType, obj)); + return _common.QuoteParamterName(paramName); + } return string.Concat(_ado.AddslashesProcessParam(obj, mapType, mapColumn)); } } diff --git a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs index 3ecb796a..cf1cf470 100644 --- a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs +++ b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs @@ -32,6 +32,7 @@ namespace FreeSql.Internal.CommonProvider public bool IsSyncStructureToUpper { get; set; } = false; public bool IsConfigEntityFromDbFirst { get; set; } = false; public virtual bool IsNoneCommandParameter { get; set; } = false; + public virtual bool IsGenerateCommandParameterWithLambda { get; set; } = false; public bool IsLazyLoading { get; set; } = false; public abstract (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type); diff --git a/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index 7bd56748..e2d816dc 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -22,7 +22,6 @@ namespace FreeSql.Internal.CommonProvider protected int _whereTimes = 0; protected List _whereGlobalFilter; protected List _params = new List(); - protected bool _noneParameter; protected DbTransaction _transaction; protected DbConnection _connection; @@ -32,7 +31,6 @@ namespace FreeSql.Internal.CommonProvider _commonUtils = commonUtils; _commonExpression = commonExpression; _table = _commonUtils.GetTableByEntity(typeof(T1)); - _noneParameter = _orm.CodeFirst.IsNoneCommandParameter; this.Where(_commonUtils.WhereObject(_table, "", dywhere)); if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure(); _whereGlobalFilter = _orm.GlobalFilter.GetFilters(); @@ -87,7 +85,7 @@ namespace FreeSql.Internal.CommonProvider } public abstract List ExecuteDeleted(); - public IDelete Where(Expression> exp) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, exp?.Body, null, _noneParameter ? _params : null)); + public IDelete Where(Expression> exp) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, exp?.Body, null, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); public IDelete Where(string sql, object parms = null) { if (string.IsNullOrEmpty(sql)) return this; diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 3e292a00..1135f7bd 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -35,7 +35,6 @@ namespace FreeSql.Internal.CommonProvider protected Action _trackToList; protected List> _includeToList = new List>(); protected bool _distinct; - protected bool _noneParameter; protected Expression _selectExpression; protected List _whereCascadeExpression = new List(); protected List _whereGlobalFilter; @@ -106,7 +105,6 @@ namespace FreeSql.Internal.CommonProvider toType.GetField("_trackToList", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._trackToList); toType.GetField("_includeToList", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._includeToList); toType.GetField("_distinct", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._distinct); - toType.GetField("_noneParameter", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._noneParameter); toType.GetField("_selectExpression", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._selectExpression); toType.GetField("_whereCascadeExpression", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._whereCascadeExpression); toType.GetField("_whereGlobalFilter", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._whereGlobalFilter); @@ -118,7 +116,6 @@ namespace FreeSql.Internal.CommonProvider _commonUtils = commonUtils; _commonExpression = commonExpression; _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T1)), Alias = "a", On = null, Type = SelectTableInfoType.From }); - _noneParameter = _orm.CodeFirst.IsNoneCommandParameter; this.Where(_commonUtils.WhereObject(_tables.First().Table, "a.", dywhere)); if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure(); } @@ -1054,7 +1051,7 @@ namespace FreeSql.Internal.CommonProvider return this.ToListMapReader((map, field.Length > 0 ? field.Remove(0, 2).ToString() : null)).FirstOrDefault(); } - protected TSelect InternalWhere(Expression exp) => exp == null ? this as TSelect : this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp, null, _whereCascadeExpression, _noneParameter ? _params : null)); + protected TSelect InternalWhere(Expression exp) => exp == null ? this as TSelect : this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); #endregion #if net40 diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs index 39affc4c..445641dc 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs @@ -153,21 +153,21 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)) : this; + return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)) : this; } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).Any(); } #if net40 @@ -226,7 +226,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).AnyAsync(); } #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 916e22ba..c84f2328 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -543,23 +543,48 @@ namespace FreeSql.Internal.CommonProvider var t1parm = Expression.Parameter(typeof(T1)); Expression membersExp = t1parm; - foreach (var mem in members) membersExp = Expression.MakeMemberAccess(membersExp, mem.Member); + Expression membersExpNotNull = null; + foreach (var mem in members) + { + membersExp = Expression.MakeMemberAccess(membersExp, mem.Member); + var expNotNull = Expression.NotEqual(membersExp, Expression.Constant(null)); + if (membersExpNotNull == null) membersExpNotNull = expNotNull; + else membersExpNotNull = Expression.AndAlso(membersExpNotNull, expNotNull); + } members.Clear(); var listValueExp = Expression.Parameter(typeof(List), "listValue"); - var setListValue = Expression.Lambda>>( - Expression.Assign( - Expression.MakeMemberAccess(membersExp, collMem.Member), - Expression.TypeAs(listValueExp, collMem.Type) - ), t1parm, listValueExp).Compile(); + var setListValue = membersExpNotNull == null ? + Expression.Lambda>>( + Expression.Assign( + Expression.MakeMemberAccess(membersExp, collMem.Member), + Expression.TypeAs(listValueExp, collMem.Type) + ), t1parm, listValueExp).Compile() : + Expression.Lambda>>( + Expression.IfThen( + membersExpNotNull, + Expression.Assign( + Expression.MakeMemberAccess(membersExp, collMem.Member), + Expression.TypeAs(listValueExp, collMem.Type) + ) + ), t1parm, listValueExp).Compile(); var returnTarget = Expression.Label(typeof(object)); var propertyNameExp = Expression.Parameter(typeof(string), "propertyName"); - var getListValue1 = Expression.Lambda>( - Expression.Block( - Expression.Return(returnTarget, Expression.Call(null, GetEntityValueWithPropertyNameMethod, Expression.Constant(_orm), Expression.Constant(membersExp.Type), membersExp, propertyNameExp)), - Expression.Label(returnTarget, Expression.Default(typeof(object))) - ), t1parm, propertyNameExp).Compile(); + var getListValue1 = membersExpNotNull == null ? + Expression.Lambda>( + Expression.Block( + Expression.Return(returnTarget, Expression.Call(null, GetEntityValueWithPropertyNameMethod, Expression.Constant(_orm), Expression.Constant(membersExp.Type), membersExp, propertyNameExp)), + Expression.Label(returnTarget, Expression.Default(typeof(object))) + ), t1parm, propertyNameExp).Compile(): + Expression.Lambda>( + Expression.Block( + Expression.IfThen( + membersExpNotNull, + Expression.Return(returnTarget, Expression.Call(null, GetEntityValueWithPropertyNameMethod, Expression.Constant(_orm), Expression.Constant(membersExp.Type), membersExp, propertyNameExp)) + ), + Expression.Label(returnTarget, Expression.Default(typeof(object))) + ), t1parm, propertyNameExp).Compile(); var getListValue2 = new List>(); for (var j = 0; j < tbrefOneToManyColumns.Count; j++) @@ -570,13 +595,29 @@ namespace FreeSql.Internal.CommonProvider continue; } Expression tbrefOneToManyColumnsMembers = t1parm; - foreach (var mem in tbrefOneToManyColumns[j]) tbrefOneToManyColumnsMembers = Expression.MakeMemberAccess(tbrefOneToManyColumnsMembers, mem.Member); + Expression tbrefOneToManyColumnsMembersNotNull = null; + foreach (var mem in tbrefOneToManyColumns[j]) + { + tbrefOneToManyColumnsMembers = Expression.MakeMemberAccess(tbrefOneToManyColumnsMembers, mem.Member); + var expNotNull = Expression.NotEqual(membersExp, Expression.Constant(null)); + if (tbrefOneToManyColumnsMembersNotNull == null) tbrefOneToManyColumnsMembersNotNull = expNotNull; + else tbrefOneToManyColumnsMembersNotNull = Expression.AndAlso(tbrefOneToManyColumnsMembersNotNull, expNotNull); + } tbrefOneToManyColumns[j].Clear(); - getListValue2.Add(Expression.Lambda>( - Expression.Block( - Expression.Return(returnTarget, Expression.Call(null, GetEntityValueWithPropertyNameMethod, Expression.Constant(_orm), Expression.Constant(tbrefOneToManyColumnsMembers.Type), tbrefOneToManyColumnsMembers, propertyNameExp)), - Expression.Label(returnTarget, Expression.Default(typeof(object))) - ), t1parm, propertyNameExp).Compile()); + getListValue2.Add(tbrefOneToManyColumnsMembersNotNull == null ? + Expression.Lambda>( + Expression.Block( + Expression.Return(returnTarget, Expression.Call(null, GetEntityValueWithPropertyNameMethod, Expression.Constant(_orm), Expression.Constant(tbrefOneToManyColumnsMembers.Type), tbrefOneToManyColumnsMembers, propertyNameExp)), + Expression.Label(returnTarget, Expression.Default(typeof(object))) + ), t1parm, propertyNameExp).Compile() : + Expression.Lambda>( + Expression.Block( + Expression.IfThen( + tbrefOneToManyColumnsMembersNotNull, + Expression.Return(returnTarget, Expression.Call(null, GetEntityValueWithPropertyNameMethod, Expression.Constant(_orm), Expression.Constant(tbrefOneToManyColumnsMembers.Type), tbrefOneToManyColumnsMembers, propertyNameExp)) + ), + Expression.Label(returnTarget, Expression.Default(typeof(object))) + ), t1parm, propertyNameExp).Compile()); } tbrefOneToManyColumns.Clear(); Func getListValue = (item, propName, colIndex) => @@ -706,7 +747,8 @@ namespace FreeSql.Internal.CommonProvider { if (tbref.Columns.Count == 1) { - var dicListKey = getListValue(item, tbref.Columns[0].CsName, 0).ToString(); + var dicListKey = getListValue(item, tbref.Columns[0].CsName, 0)?.ToString(); + if (dicListKey == null) continue; var dicListVal = Tuple.Create(item, new List()); if (dicList.TryGetValue(dicListKey, out var items) == false) dicList.Add(dicListKey, items = new List>>()); @@ -891,7 +933,8 @@ namespace FreeSql.Internal.CommonProvider { if (tbref.Columns.Count == 1) { - var dicListKey = getListValue1(item, tbref.Columns[0].CsName).ToString(); + var dicListKey = getListValue1(item, tbref.Columns[0].CsName)?.ToString(); + if (dicListKey == null) continue; var dicListVal = Tuple.Create(item, new List()); if (dicList.TryGetValue(dicListKey, out var items) == false) dicList.Add(dicListKey, items = new List>>()); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs index 8891dc13..25dc239e 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs @@ -130,21 +130,21 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).Any(); } #if net40 @@ -203,7 +203,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).AnyAsync(); } #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs index dd18f595..f355d1b5 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs @@ -133,21 +133,21 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).Any(); } #if net40 @@ -206,7 +206,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).AnyAsync(); } #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs index 64597f32..04b4cc8d 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs @@ -136,21 +136,21 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).Any(); } #if net40 @@ -209,7 +209,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).AnyAsync(); } #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs index af16c69b..c7438f9b 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs @@ -139,21 +139,21 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).Any(); } #if net40 @@ -212,7 +212,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).AnyAsync(); } #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs index ed6058ba..de717933 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs @@ -142,21 +142,21 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).Any(); } #if net40 @@ -215,7 +215,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).AnyAsync(); } #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs index 674f4503..1ec020d8 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs @@ -145,21 +145,21 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).Any(); } #if net40 @@ -218,7 +218,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).AnyAsync(); } #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs index 324fe9a0..fd6b33fe 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs @@ -149,21 +149,21 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).Any(); } #if net40 @@ -222,7 +222,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).AnyAsync(); } #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs index fcf28472..ff3098ef 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs @@ -147,20 +147,20 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).Any(); } #if net40 @@ -169,7 +169,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).AnyAsync(); } Task ISelect.ToDataTableAsync(Expression> select) diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 5eac94a6..28d60260 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -424,7 +424,7 @@ namespace FreeSql.Internal.CommonProvider return this; } - public IUpdate Where(Expression> expression) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, expression?.Body, null, _noneParameter ? _params : null)); + public IUpdate Where(Expression> expression) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, expression?.Body, null, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); public IUpdate Where(string sql, object parms = null) { if (string.IsNullOrEmpty(sql)) return this; diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index 4b7d9d01..1adbebfa 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -48,25 +48,6 @@ namespace FreeSql.Internal _orm = orm; } - static Regex _regexSize = new Regex(@"\(([^\)]+)\)", RegexOptions.Compiled); - internal void SetParameterSize(DbParameter parm, string dbtypeFull, ColumnInfo col) - { - if (col == null) return; - if (string.IsNullOrEmpty(dbtypeFull)) return; - var m = _regexSize.Match(dbtypeFull); - if (m.Success == false) return; - var sizeStr = m.Groups[1].Value.Trim(); - if (string.Compare(sizeStr, "max", true) == 0) - { - parm.Size = -1; - return; - } - var sizeArr = sizeStr.Split(','); - if (int.TryParse(sizeArr[0], out var size) == false) return; - if (sizeArr.Length > 1 && int.TryParse(sizeArr[1], out var size2)) size += size2; - parm.Size = size; - } - ConcurrentDictionary dicConfigEntity = new ConcurrentDictionary(); public ICodeFirst ConfigEntity(Action> entity) { diff --git a/FreeSql/Internal/Model/ColumnInfo.cs b/FreeSql/Internal/Model/ColumnInfo.cs index fbc26e05..84780850 100644 --- a/FreeSql/Internal/Model/ColumnInfo.cs +++ b/FreeSql/Internal/Model/ColumnInfo.cs @@ -13,6 +13,10 @@ namespace FreeSql.Internal.Model public Type CsType { get; set; } public ColumnAttribute Attribute { get; set; } public string Comment { get; internal set; } + public string DbTypeText { get; internal set; } + public int DbSize { get; internal set; } + public byte DbPrecision { get; internal set; } + public byte DbScale { get; internal set; } static ConcurrentDictionary> _dicGetMapValue = new ConcurrentDictionary>(); public object GetMapValue(object obj) diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index cecb8816..5904d7fa 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -299,6 +299,34 @@ namespace FreeSql.Internal col.Attribute.IsNullable = false; col.Attribute.DbType = col.Attribute.DbType.Replace("NOT NULL", ""); } + foreach (var col in trytb.Columns.Values) + { + var ltp = @"\(([^\)]+)\)"; + col.DbTypeText = Regex.Replace(col.Attribute.DbType.Replace("NOT NULL", "").Trim(), ltp, ""); + var m = Regex.Match(col.Attribute.DbType, ltp); + if (m.Success == false) continue; + var sizeStr = m.Groups[1].Value.Trim(); + if (string.Compare(sizeStr, "max", true) == 0) + { + col.DbSize = -1; + continue; + } + var sizeArr = sizeStr.Split(','); + if (int.TryParse(sizeArr[0].Trim(), out var size) == false) continue; + if (col.Attribute.MapType.NullableTypeOrThis() == typeof(DateTime)) + { + col.DbScale = (byte)size; + continue; + } + if (sizeArr.Length == 1) + { + col.DbSize = size; + continue; + } + if (byte.TryParse(sizeArr[1], out var scale) == false) continue; + col.DbPrecision = (byte)size; + col.DbScale = scale; + } tbc.AddOrUpdate(entity, trytb, (oldkey, oldval) => trytb); #region 查找导航属性的关系、virtual 属性延时加载,动态产生新的重写类 diff --git a/Providers/FreeSql.Provider.MySql/MySqlUtils.cs b/Providers/FreeSql.Provider.MySql/MySqlUtils.cs index c9a70ec7..e76342d8 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlUtils.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlUtils.cs @@ -21,26 +21,31 @@ namespace FreeSql.MySql public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; - if (type == null && col != null) type = col.Attribute.MapType ?? col.CsType; var ret = new MySqlParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; - var tp = _orm.CodeFirst.GetDbInfo(type)?.type; - if (tp != null) + var dbtype = (MySqlDbType)_orm.CodeFirst.GetDbInfo(type)?.type; + if (col != null) { - if (col != null && type == typeof(string)) + var dbtype2 = (MySqlDbType)_orm.DbFirst.GetDbType(new DatabaseModel.DbColumnInfo { DbTypeText = col.DbTypeText, DbTypeTextFull = col.Attribute.DbType, MaxLength = col.DbSize }); + switch (dbtype2) { - if (col.Attribute.DbType.Contains("VARCHAR")) ret.MySqlDbType = MySqlDbType.VarChar; - else if (col.Attribute.DbType.Contains("CHAR")) ret.MySqlDbType = MySqlDbType.VarChar; - else if (col.Attribute.DbType.Contains("TEXT")) ret.MySqlDbType = MySqlDbType.Text; - else ret.MySqlDbType = MySqlDbType.VarChar; + case MySqlDbType.Binary: + case MySqlDbType.VarBinary: + break; + default: + dbtype = dbtype2; + if (col.DbSize != 0) ret.Size = col.DbSize; + if (col.DbPrecision != 0) ret.Precision = col.DbPrecision; + if (col.DbScale != 0) ret.Scale = col.DbScale; + break; } - else if ((MySqlDbType)tp.Value == MySqlDbType.Geometry) - { - ret.MySqlDbType = MySqlDbType.Text; - if (value != null) ret.Value = (value as MygisGeometry).AsText(); - } - else - ret.MySqlDbType = (MySqlDbType)tp.Value; } + if (dbtype == MySqlDbType.Geometry) + { + ret.MySqlDbType = MySqlDbType.Text; + if (value != null) ret.Value = (value as MygisGeometry).AsText(); + } + else + ret.MySqlDbType = dbtype; _params?.Add(ret); return ret; } diff --git a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs index a1cfc9d6..1fe7e253 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs +++ b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs @@ -21,30 +21,35 @@ namespace FreeSql.MySql public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; - if (type == null && col != null) type = col.Attribute.MapType ?? col.CsType; var ret = new MySqlParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; - var tp = _orm.CodeFirst.GetDbInfo(type)?.type; - if (tp != null) + var dbtype = (MySqlDbType)_orm.CodeFirst.GetDbInfo(type)?.type; + if (col != null) { - if (col != null && type == typeof(string)) + var dbtype2 = (MySqlDbType)_orm.DbFirst.GetDbType(new DatabaseModel.DbColumnInfo { DbTypeText = col.DbTypeText, DbTypeTextFull = col.Attribute.DbType, MaxLength = col.DbSize }); + switch (dbtype2) { - if (col.Attribute.DbType.Contains("VARCHAR")) ret.MySqlDbType = MySqlDbType.VarChar; - else if (col.Attribute.DbType.Contains("CHAR")) ret.MySqlDbType = MySqlDbType.VarChar; - else if (col.Attribute.DbType.Contains("TEXT")) ret.MySqlDbType = MySqlDbType.Text; - else ret.MySqlDbType = MySqlDbType.VarChar; - } - else if ((MySqlDbType)tp.Value == MySqlDbType.Geometry) - { - ret.MySqlDbType = MySqlDbType.Text; - if (value != null) ret.Value = (value as MygisGeometry).AsText(); - } - else - { - ret.MySqlDbType = (MySqlDbType)tp.Value; - if (ret.MySqlDbType == MySqlDbType.Enum && value != null) - ret.Value = (long)Convert.ChangeType(value, typeof(long)) + 1; + //case MySqlDbType.Binary: + //case MySqlDbType.VarBinary: + // break; + default: + dbtype = dbtype2; + if (col.DbSize != 0) ret.Size = col.DbSize; + if (col.DbPrecision != 0) ret.Precision = col.DbPrecision; + if (col.DbScale != 0) ret.Scale = col.DbScale; + break; } } + if (dbtype == MySqlDbType.Geometry) + { + ret.MySqlDbType = MySqlDbType.Text; + if (value != null) ret.Value = (value as MygisGeometry).AsText(); + } + else + { + ret.MySqlDbType = dbtype; + if (ret.MySqlDbType == MySqlDbType.Enum && value != null) + ret.Value = (long)Convert.ChangeType(value, typeof(long)) + 1; + } _params?.Add(ret); return ret; } diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs index c4db2879..c589bcdb 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs @@ -20,7 +20,6 @@ namespace FreeSql.Odbc.Default public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; - if (type == null && col != null) type = col.Attribute.MapType ?? col.CsType; if (value?.Equals(DateTime.MinValue) == true) value = new DateTime(1970, 1, 1); var ret = new OdbcParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; var tp = _orm.CodeFirst.GetDbInfo(type)?.type; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs index 4370826b..dc53f35a 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs @@ -21,7 +21,6 @@ namespace FreeSql.Odbc.MySql public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; - if (type == null && col != null) type = col.Attribute.MapType ?? col.CsType; var ret = new OdbcParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; var tp = _orm.CodeFirst.GetDbInfo(type)?.type; if (tp != null) diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs index c2040d23..8827a089 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs @@ -19,7 +19,6 @@ namespace FreeSql.Odbc.Oracle public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; - if (type == null && col != null) type = col.Attribute.MapType ?? col.CsType; var dbtype = (OdbcType)_orm.CodeFirst.GetDbInfo(type)?.type; switch (dbtype) { diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs index bed333aa..c9bcbc21 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs @@ -67,7 +67,6 @@ namespace FreeSql.Odbc.PostgreSQL public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; - if (type == null && col != null) type = col.Attribute.MapType ?? col.CsType; if (value != null) value = getParamterValue(type, value); var ret = new OdbcParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; //if (value.GetType().IsEnum || value.GetType().GenericTypeArguments.FirstOrDefault()?.IsEnum == true) { diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs index c4497b17..02f18715 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs @@ -25,7 +25,6 @@ namespace FreeSql.Odbc.SqlServer public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; - if (type == null && col != null) type = col.Attribute.MapType ?? col.CsType; if (value?.Equals(DateTime.MinValue) == true) value = new DateTime(1970, 1, 1); var ret = new OdbcParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; var tp = _orm.CodeFirst.GetDbInfo(type)?.type; diff --git a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs index cd0d8f79..11c46adc 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs @@ -19,7 +19,6 @@ namespace FreeSql.Oracle public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; - if (type == null && col != null) type = col.Attribute.MapType ?? col.CsType; var dbtype = (OracleDbType)_orm.CodeFirst.GetDbInfo(type)?.type; if (dbtype == OracleDbType.Boolean) { @@ -27,15 +26,24 @@ namespace FreeSql.Oracle else value = (bool)value == true ? 1 : 0; dbtype = OracleDbType.Int16; } - else if (col != null && type == typeof(string)) - { - if (col.Attribute.DbType.Contains("NVARCHAR2")) dbtype = OracleDbType.NVarchar2; - else if (col.Attribute.DbType.Contains("VARCHAR2")) dbtype = OracleDbType.Varchar2; - else if (col.Attribute.DbType.Contains("NCHAR")) dbtype = OracleDbType.NChar; - else if (col.Attribute.DbType.Contains("CHAR")) dbtype = OracleDbType.Char; - else dbtype = OracleDbType.NVarchar2; - } var ret = new OracleParameter { ParameterName = QuoteParamterName(parameterName), OracleDbType = dbtype, Value = value }; + if (col != null) + { + var dbtype2 = (OracleDbType)_orm.DbFirst.GetDbType(new DatabaseModel.DbColumnInfo { DbTypeTextFull = col.Attribute.DbType.Replace("NOT NULL", "").Trim(), DbTypeText = col.DbTypeText }); + switch (dbtype2) + { + case OracleDbType.Char: + case OracleDbType.Varchar2: + case OracleDbType.NChar: + case OracleDbType.NVarchar2: + case OracleDbType.Decimal: + dbtype = dbtype2; + if (col.DbSize != 0) ret.Size = col.DbSize; + if (col.DbPrecision != 0) ret.Precision = col.DbPrecision; + if (col.DbScale != 0) ret.Scale = col.DbScale; + break; + } + } _params?.Add(ret); return ret; } diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs index b4556b31..ce2213a7 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs @@ -82,24 +82,23 @@ namespace FreeSql.PostgreSQL public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; - if (type == null && col != null) type = col.Attribute.MapType ?? col.CsType; if (value != null) value = getParamterValue(type, value); var ret = new NpgsqlParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; //if (value.GetType().IsEnum || value.GetType().GenericTypeArguments.FirstOrDefault()?.IsEnum == true) { // ret.DataTypeName = ""; //} else { var tp = _orm.CodeFirst.GetDbInfo(type)?.type; - if (tp != null) + if (tp != null) ret.NpgsqlDbType = (NpgsqlDbType)tp.Value; + if (col != null) { - if (col != null && type == typeof(string)) + var dbtype = (NpgsqlDbType)_orm.DbFirst.GetDbType(new DatabaseModel.DbColumnInfo { DbTypeText = col.DbTypeText }); + if (dbtype != NpgsqlDbType.Unknown) { - if (col.Attribute.DbType.Contains("VARCHAR")) ret.NpgsqlDbType = NpgsqlDbType.Varchar; - else if (col.Attribute.DbType.Contains("CHAR")) ret.NpgsqlDbType = NpgsqlDbType.Char; - else if (col.Attribute.DbType.Contains("TEXT")) ret.NpgsqlDbType = NpgsqlDbType.Text; - else ret.NpgsqlDbType = NpgsqlDbType.Varchar; + ret.NpgsqlDbType = 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; } - else - ret.NpgsqlDbType = (NpgsqlDbType)tp.Value; } //} _params?.Add(ret); diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs index beb264dd..56659c60 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs @@ -25,24 +25,20 @@ namespace FreeSql.SqlServer public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; - if (type == null && col != null) type = col.Attribute.MapType ?? col.CsType; if (value?.Equals(DateTime.MinValue) == true) value = new DateTime(1970, 1, 1); var ret = new SqlParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; var tp = _orm.CodeFirst.GetDbInfo(type)?.type; - if (tp != null) + if (tp != null) ret.SqlDbType = (SqlDbType)tp.Value; + if (col != null) { - if (col != null && type == typeof(string)) + var dbtype = (SqlDbType)_orm.DbFirst.GetDbType(new DatabaseModel.DbColumnInfo { DbTypeText = col.DbTypeText }); + if (dbtype != SqlDbType.Variant) { - if (col.Attribute.DbType.Contains("NVARCHAR")) ret.SqlDbType = SqlDbType.NVarChar; - else if (col.Attribute.DbType.Contains("VARCHAR")) ret.SqlDbType = SqlDbType.VarChar; - else if (col.Attribute.DbType.Contains("NCHAR")) ret.SqlDbType = SqlDbType.NChar; - else if (col.Attribute.DbType.Contains("CHAR")) ret.SqlDbType = SqlDbType.Char; - else if (col.Attribute.DbType.Contains("NTEXT")) ret.SqlDbType = SqlDbType.NText; - else if (col.Attribute.DbType.Contains("TEXT")) ret.SqlDbType = SqlDbType.Text; - else ret.SqlDbType = SqlDbType.VarChar; + ret.SqlDbType = 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; } - else - ret.SqlDbType = (SqlDbType)tp.Value; } _params?.Add(ret); return ret; diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs index aecfde24..498ef244 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs @@ -19,7 +19,6 @@ namespace FreeSql.Sqlite public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; - if (type == null && col != null) type = col.Attribute.MapType ?? col.CsType; var dbtype = (DbType)_orm.CodeFirst.GetDbInfo(type)?.type; switch (dbtype) {