Bladeren bron

- support bool and bool? column mapping
- [Vitorm.SqlServer] fix bool type was not supported in database issue (especially in select sentence)

Lith 10 maanden geleden
bovenliggende
commit
45ea03d4d6

+ 3 - 1
doc/ReleaseLog.md

@@ -8,7 +8,9 @@
 > userQuery.Select(user => new { name = $"{user.id}_{user.fatherId}_{user.motherId}" });
 
 - fix treat String.Add as Numeric.Add issue
-
+- support bool and bool? column mapping
+- [Vitorm.SqlServer] fix bool type was not supported in database issue (especially in select sentence)
+- [Vitorm.ClickHouse] fix String.Add null value and cast issue : ifNull(  cast( (userFatherId) as Nullable(String) ) , ''  )
 -----------------------
 # 1.1.0
 

+ 2 - 2
src/Vitorm.SqlServer/SqlTranslate/QueryTranslateService.cs

@@ -43,7 +43,7 @@ ROW_NUMBER() OVER(ORDER BY @@RowCount) AS [__RowNumber__]
                 case "" or null or "ToList" or nameof(Orm_Extensions.ToExecuteString):
                     {
                         var reader = new DataReader();
-                        return prefix + " " + BuildReader(arg, stream, reader);
+                        return prefix + " " + BuildDataReader(arg, stream, reader);
                     }
                 case "FirstOrDefault" or "First" or "LastOrDefault" or "Last":
                     {
@@ -55,7 +55,7 @@ ROW_NUMBER() OVER(ORDER BY @@RowCount) AS [__RowNumber__]
 
                         var nullable = stream.method.Contains("OrDefault");
                         var reader = new DataReader_FirstRow { nullable = nullable };
-                        return prefix + " " + BuildReader(arg, stream, reader);
+                        return prefix + " " + BuildDataReader(arg, stream, reader);
                     }
             }
             throw new NotSupportedException("not supported method: " + stream.method);

+ 34 - 1
src/Vitorm.SqlServer/SqlTranslateService.cs

@@ -54,6 +54,29 @@ namespace Vitorm.SqlServer
 
 
         #region EvalExpression
+
+        /// <summary>
+        /// evaluate column in select,  for example :  "select (u.id + 100) as newId"
+        /// </summary>
+        /// <param name="arg"></param>
+        /// <param name="data"></param>
+        /// <param name="columnType"></param>
+        /// <returns></returns>
+        public override string EvalSelectExpression(QueryTranslateArgument arg, ExpressionNode data, Type columnType = null)
+        {
+            var selectFieldSentence = base.EvalSelectExpression(arg, data, columnType);
+            if (columnType == typeof(bool) || columnType == typeof(bool?))
+            {
+                if (!selectFieldSentence.StartsWith("IIF(", StringComparison.OrdinalIgnoreCase))
+                {
+                    // select IIF(userFatherId is not null, 1, 0) as hasFather, * from [User]
+                    return $"IIF({base.EvalSelectExpression(arg, data, columnType)}, 1, 0)";
+                }
+            }
+            return selectFieldSentence;
+        }
+
+
         /// <summary>
         /// read where or value or on
         /// </summary>
@@ -65,6 +88,16 @@ namespace Vitorm.SqlServer
         {
             switch (data.nodeType)
             {
+                case NodeType.Constant:
+                    {
+                        ExpressionNode_Constant constant = data;
+                        var value = constant.value;
+                        if (value is bool boolean)
+                        {
+                            return boolean ? "1" : "0";
+                        }
+                        break;
+                    }
                 case NodeType.MethodCall:
                     {
                         ExpressionNode_MethodCall methodCall = data;
@@ -146,7 +179,7 @@ namespace Vitorm.SqlServer
                     }
                 case nameof(ExpressionType.Conditional):
                     {
-                        // IIF(`t0`.`fatherId` is not null,true, false)
+                        // IIF(`t0`.`fatherId` is not null, 1, 0)
                         ExpressionNode_Conditional conditional = data;
                         return $"IIF({EvalExpression(arg, conditional.Conditional_GetTest())},{EvalExpression(arg, conditional.Conditional_GetIfTrue())},{EvalExpression(arg, conditional.Conditional_GetIfFalse())})";
                     }

+ 21 - 0
src/Vitorm/Sql/DataReader/EntityReader/EntityConstructor/ConstantValueReader.cs

@@ -0,0 +1,21 @@
+using System;
+using System.Data;
+
+namespace Vitorm.Sql.DataReader.EntityReader.EntityConstructor
+{
+    public class ConstantValueReader : IValueReader
+    {
+        protected object value;
+        public ConstantValueReader(object value, Type valueType = null)
+        {
+            if (valueType != null) value = TypeUtil.ConvertToType(value, valueType);
+            this.value = value;
+        }
+
+        public object Read(IDataReader reader)
+        {
+            return value;
+        }
+    }
+
+}

+ 5 - 1
src/Vitorm/Sql/DataReader/EntityReader/EntityConstructor/EntityReader.cs

@@ -22,7 +22,6 @@ namespace Vitorm.Sql.DataReader.EntityReader.EntityConstructor
                 case NodeType.New:
                     {
                         ExpressionNode_New newNode = resultSelector;
-
                         return new ModelReader(config, this, newNode);
                     }
                 case NodeType.Member:
@@ -48,6 +47,11 @@ namespace Vitorm.Sql.DataReader.EntityReader.EntityConstructor
                             return new EntityReader_(config, tableName, argType, entityDescriptor);
                         }
                     }
+                case NodeType.Constant:
+                    {
+                        ExpressionNode_Constant constant = resultSelector;
+                        return new ConstantValueReader(constant.value, constant.valueType?.ToType());
+                    }
                 default:
                     {
                         // Value

+ 1 - 1
src/Vitorm/Sql/DataReader/EntityReader/EntityConstructor/ValueReader.cs

@@ -7,7 +7,7 @@ namespace Vitorm.Sql.DataReader.EntityReader.EntityConstructor
     public class ValueReader : SqlFieldReader, IValueReader
     {
         public ValueReader(EntityReaderConfig config, Type valueType, ExpressionNode valueNode)
-            : base(valueType, config.sqlColumns.AddSqlColumnAndGetIndex(config, valueNode))
+            : base(valueType, config.sqlColumns.AddSqlColumnAndGetIndex(config, valueNode, valueType))
         {
         }
     }

+ 2 - 2
src/Vitorm/Sql/DataReader/SqlColumns.cs

@@ -72,11 +72,11 @@ namespace Vitorm.Sql.DataReader
             return sqlColumnIndex;
         }
 
-        public int AddSqlColumnAndGetIndex(EntityReaderConfig config, ExpressionNode valueNode)
+        public int AddSqlColumnAndGetIndex(EntityReaderConfig config, ExpressionNode valueNode, Type valueType)
         {
             if (valueNode.nodeType == NodeType.Member) return AddSqlColumnAndGetIndex(config.sqlTranslateService, (ExpressionNode_Member)valueNode, config.queryTranslateArgument.dbContext);
 
-            var sqlColumnSentence = config.sqlTranslateService.EvalExpression(config.queryTranslateArgument, valueNode);
+            var sqlColumnSentence = config.sqlTranslateService.EvalSelectExpression(config.queryTranslateArgument, valueNode, valueType);
 
             return AddSqlColumnAndGetIndex(sqlColumnSentence);
         }

+ 1 - 1
src/Vitorm/Sql/SqlTranslate/BaseQueryTranslateService.cs

@@ -158,7 +158,7 @@ namespace Vitorm.Sql.SqlTranslate
             }
             throw new NotSupportedException();
         }
-        protected virtual string BuildReader(QueryTranslateArgument arg, CombinedStream stream, DataReader.DataReader reader)
+        protected virtual string BuildDataReader(QueryTranslateArgument arg, CombinedStream stream, DataReader.DataReader reader)
         {
             var resultEntityType = arg.resultEntityType;
             ExpressionNode selectedFields = stream.select?.fields;

+ 8 - 0
src/Vitorm/Sql/SqlTranslate/ISqlTranslateService.cs

@@ -30,6 +30,14 @@ namespace Vitorm.Sql.SqlTranslate
         string GetSqlField(string tableName, string columnName);
         string GetSqlField(ExpressionNode_Member member, DbContext dbContext);
 
+        /// <summary>
+        /// evaluate column in select,  for example :  "select (u.id + 100) as newId"
+        /// </summary>
+        /// <param name="arg"></param>
+        /// <param name="data"></param>
+        /// <param name="columnType"></param>
+        /// <returns></returns>
+        string EvalSelectExpression(QueryTranslateArgument arg, ExpressionNode data, Type columnType = null);
         string EvalExpression(QueryTranslateArgument arg, ExpressionNode data);
 
         // #0 Schema :  PrepareCreate PrepareDrop

+ 2 - 2
src/Vitorm/Sql/SqlTranslate/QueryTranslateService.cs

@@ -38,7 +38,7 @@ namespace Vitorm.Sql.SqlTranslate
                 case "" or null or "ToList" or nameof(Orm_Extensions.ToExecuteString):
                     {
                         var reader = new DataReader.DataReader();
-                        return prefix + " " + BuildReader(arg, stream, reader);
+                        return prefix + " " + BuildDataReader(arg, stream, reader);
                     }
                 case "FirstOrDefault" or "First" or "LastOrDefault" or "Last":
                     {
@@ -50,7 +50,7 @@ namespace Vitorm.Sql.SqlTranslate
 
                         var nullable = stream.method.Contains("OrDefault");
                         var reader = new DataReader_FirstRow { nullable = nullable };
-                        return prefix + " " + BuildReader(arg, stream, reader);
+                        return prefix + " " + BuildDataReader(arg, stream, reader);
                     }
             }
             throw new NotSupportedException("not supported method: " + stream.method);

+ 12 - 0
src/Vitorm/Sql/SqlTranslate/SqlTranslateService.cs

@@ -97,6 +97,18 @@ namespace Vitorm.Sql.SqlTranslate
 
         #region EvalExpression
 
+        /// <summary>
+        /// evaluate column in select,  for example :  "select (u.id + 100) as newId"
+        /// </summary>
+        /// <param name="arg"></param>
+        /// <param name="data"></param>
+        /// <param name="columnType"></param>
+        /// <returns></returns>
+        public virtual string EvalSelectExpression(QueryTranslateArgument arg, ExpressionNode data, Type columnType = null)
+        {
+            return EvalExpression(arg, data);
+        }
+
         /// <summary>
         /// read where or value or on
         /// </summary>

+ 1 - 1
test/Vitorm.SqlServer.MsTest/CustomTest/DbFunction_Test.cs

@@ -15,7 +15,7 @@ namespace Vitorm.MsTest.CustomTest
             var userQuery = dbContext.Query<User>();
 
 
-            // select * from `User` as t0  where IIF(`t0`.`fatherId` is not null,true, false)
+            // select * from [User] where IIF(userFatherId is not null, 1, 0) = 1 
             {
                 var query = userQuery.Where(u => DbFunction.Call<int>("IIF", u.fatherId != null, 1, 0) == 1);
                 var sql = query.ToExecuteString();

+ 4 - 1
test/Vitorm.Sqlite.MsTest/CommonTest/Query_LinqMethods_Test.cs

@@ -124,7 +124,10 @@ namespace Vitorm.MsTest.CommonTest
 
                 var userList = query.ToList();
                 Assert.AreEqual(6, userList.Count);
-                Assert.AreEqual("1_4_6", userList.First().uniqueId1);
+                Assert.AreEqual("1_4_6", userList[0].uniqueId1);
+                Assert.AreEqual("1_4_6", userList[0].uniqueId2);
+                Assert.AreEqual("4__", userList[3].uniqueId1);
+                Assert.AreEqual("4__", userList[3].uniqueId2);
             }
 
         }