mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 01:05:27 +08:00 
			
		
		
		
	- 修复 sqlserver 解析 cast(.. as nvarchar) 截断长度 30 的问题;#335
This commit is contained in:
		@@ -876,7 +876,7 @@ FROM [tb_topic22] a", subquery);
 | 
				
			|||||||
            var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql();
 | 
					            var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql();
 | 
				
			||||||
            Assert.Equal(@"SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] 
 | 
					            Assert.Equal(@"SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] 
 | 
				
			||||||
FROM [tb_topic22] a 
 | 
					FROM [tb_topic22] a 
 | 
				
			||||||
WHERE (((cast(a.[Id] as nvarchar)) in (SELECT b.[Title] 
 | 
					WHERE (((cast(a.[Id] as nvarchar(100))) in (SELECT b.[Title] 
 | 
				
			||||||
	FROM [tb_topic22] b)))", subquery);
 | 
						FROM [tb_topic22] b)))", subquery);
 | 
				
			||||||
            var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList();
 | 
					            var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -925,7 +925,7 @@ FROM [tb_topic22] a", subquery);
 | 
				
			|||||||
            var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql();
 | 
					            var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql();
 | 
				
			||||||
            Assert.Equal(@"SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] 
 | 
					            Assert.Equal(@"SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] 
 | 
				
			||||||
FROM [tb_topic22] a 
 | 
					FROM [tb_topic22] a 
 | 
				
			||||||
WHERE (((cast(a.[Id] as nvarchar)) in (SELECT b.[Title] 
 | 
					WHERE (((cast(a.[Id] as nvarchar(100))) in (SELECT b.[Title] 
 | 
				
			||||||
	FROM [tb_topic22] b)))", subquery);
 | 
						FROM [tb_topic22] b)))", subquery);
 | 
				
			||||||
            var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList();
 | 
					            var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,7 +36,10 @@ namespace FreeSql.Odbc.SqlServer
 | 
				
			|||||||
                            case "System.Int64": return $"cast({getExp(operandExp)} as bigint)";
 | 
					                            case "System.Int64": return $"cast({getExp(operandExp)} as bigint)";
 | 
				
			||||||
                            case "System.SByte": return $"cast({getExp(operandExp)} as tinyint)";
 | 
					                            case "System.SByte": return $"cast({getExp(operandExp)} as tinyint)";
 | 
				
			||||||
                            case "System.Single": return $"cast({getExp(operandExp)} as decimal(14,7))";
 | 
					                            case "System.Single": return $"cast({getExp(operandExp)} as decimal(14,7))";
 | 
				
			||||||
                            case "System.String": return operandExp.Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(operandExp)} as varchar(36))" : $"cast({getExp(operandExp)} as nvarchar)";
 | 
					                            case "System.String":
 | 
				
			||||||
 | 
					                                return gentype == typeof(Guid) ?
 | 
				
			||||||
 | 
					                                  $"cast({getExp(operandExp)} as varchar(36))" :
 | 
				
			||||||
 | 
					                                  $"cast({getExp(operandExp)} as nvarchar{(gentype.IsNumberType() || gentype.IsEnum ? "(100)" : "(max)")})";
 | 
				
			||||||
                            case "System.UInt16": return $"cast({getExp(operandExp)} as smallint)";
 | 
					                            case "System.UInt16": return $"cast({getExp(operandExp)} as smallint)";
 | 
				
			||||||
                            case "System.UInt32": return $"cast({getExp(operandExp)} as int)";
 | 
					                            case "System.UInt32": return $"cast({getExp(operandExp)} as int)";
 | 
				
			||||||
                            case "System.UInt64": return $"cast({getExp(operandExp)} as bigint)";
 | 
					                            case "System.UInt64": return $"cast({getExp(operandExp)} as bigint)";
 | 
				
			||||||
@@ -86,7 +89,10 @@ namespace FreeSql.Odbc.SqlServer
 | 
				
			|||||||
                            if (callExp.Method.DeclaringType.IsNumberType()) return "rand()";
 | 
					                            if (callExp.Method.DeclaringType.IsNumberType()) return "rand()";
 | 
				
			||||||
                            return null;
 | 
					                            return null;
 | 
				
			||||||
                        case "ToString":
 | 
					                        case "ToString":
 | 
				
			||||||
                            if (callExp.Object != null) return callExp.Arguments.Count == 0 ? (callExp.Object.Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(callExp.Object)} as varchar(36))" : $"cast({getExp(callExp.Object)} as nvarchar)") : null;
 | 
					                            var gentype2 = callExp.Object.Type.NullableTypeOrThis();
 | 
				
			||||||
 | 
					                            if (callExp.Object != null) return callExp.Arguments.Count == 0 ? (gentype2 == typeof(Guid) ?
 | 
				
			||||||
 | 
					                                    $"cast({getExp(callExp.Object)} as varchar(36))" :
 | 
				
			||||||
 | 
					                                    $"cast({getExp(callExp.Object)} as nvarchar{(gentype2.IsNumberType() || gentype2.IsEnum ? "(100)" : "(max)")})") : null;
 | 
				
			||||||
                            return null;
 | 
					                            return null;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -262,10 +268,10 @@ namespace FreeSql.Odbc.SqlServer
 | 
				
			|||||||
                    case "Contains":
 | 
					                    case "Contains":
 | 
				
			||||||
                        var args0Value = getExp(exp.Arguments[0]);
 | 
					                        var args0Value = getExp(exp.Arguments[0]);
 | 
				
			||||||
                        if (args0Value == "NULL") return $"({left}) IS NULL";
 | 
					                        if (args0Value == "NULL") return $"({left}) IS NULL";
 | 
				
			||||||
                        if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(cast({args0Value} as nvarchar)+'%')")}";
 | 
					                        if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(cast({args0Value} as nvarchar(max))+'%')")}";
 | 
				
			||||||
                        if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%'+cast({args0Value} as nvarchar))")}";
 | 
					                        if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%'+cast({args0Value} as nvarchar(max)))")}";
 | 
				
			||||||
                        if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}";
 | 
					                        if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}";
 | 
				
			||||||
                        return $"({left}) LIKE ('%'+cast({args0Value} as nvarchar)+'%')";
 | 
					                        return $"({left}) LIKE ('%'+cast({args0Value} as nvarchar(max))+'%')";
 | 
				
			||||||
                    case "ToLower": return $"lower({left})";
 | 
					                    case "ToLower": return $"lower({left})";
 | 
				
			||||||
                    case "ToUpper": return $"upper({left})";
 | 
					                    case "ToUpper": return $"upper({left})";
 | 
				
			||||||
                    case "Substring":
 | 
					                    case "Substring":
 | 
				
			||||||
@@ -336,7 +342,7 @@ namespace FreeSql.Odbc.SqlServer
 | 
				
			|||||||
                switch (exp.Method.Name)
 | 
					                switch (exp.Method.Name)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    case "Compare": return $"({getExp(exp.Arguments[0])} - ({getExp(exp.Arguments[1])}))";
 | 
					                    case "Compare": return $"({getExp(exp.Arguments[0])} - ({getExp(exp.Arguments[1])}))";
 | 
				
			||||||
                    case "DaysInMonth": return $"datepart(day, dateadd(day, -1, dateadd(month, 1, cast({getExp(exp.Arguments[0])} as varchar) + '-' + cast({getExp(exp.Arguments[1])} as varchar) + '-1')))";
 | 
					                    case "DaysInMonth": return $"datepart(day, dateadd(day, -1, dateadd(month, 1, cast({getExp(exp.Arguments[0])} as varchar(100)) + '-' + cast({getExp(exp.Arguments[1])} as varchar(100)) + '-1')))";
 | 
				
			||||||
                    case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})";
 | 
					                    case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    case "IsLeapYear":
 | 
					                    case "IsLeapYear":
 | 
				
			||||||
@@ -454,7 +460,7 @@ namespace FreeSql.Odbc.SqlServer
 | 
				
			|||||||
                    case "Subtract": return $"({left}-({args1}))";
 | 
					                    case "Subtract": return $"({left}-({args1}))";
 | 
				
			||||||
                    case "Equals": return $"({left} = {args1})";
 | 
					                    case "Equals": return $"({left} = {args1})";
 | 
				
			||||||
                    case "CompareTo": return $"({left}-({args1}))";
 | 
					                    case "CompareTo": return $"({left}-({args1}))";
 | 
				
			||||||
                    case "ToString": return $"cast({left} as varchar)";
 | 
					                    case "ToString": return $"cast({left} as varchar(100))";
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            return null;
 | 
					            return null;
 | 
				
			||||||
@@ -477,7 +483,11 @@ namespace FreeSql.Odbc.SqlServer
 | 
				
			|||||||
                    case "ToInt64": return $"cast({getExp(exp.Arguments[0])} as bigint)";
 | 
					                    case "ToInt64": return $"cast({getExp(exp.Arguments[0])} as bigint)";
 | 
				
			||||||
                    case "ToSByte": return $"cast({getExp(exp.Arguments[0])} as tinyint)";
 | 
					                    case "ToSByte": return $"cast({getExp(exp.Arguments[0])} as tinyint)";
 | 
				
			||||||
                    case "ToSingle": return $"cast({getExp(exp.Arguments[0])} as decimal(14,7))";
 | 
					                    case "ToSingle": return $"cast({getExp(exp.Arguments[0])} as decimal(14,7))";
 | 
				
			||||||
                    case "ToString": return exp.Arguments[0].Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(exp.Arguments[0])} as varchar(36))" : $"cast({getExp(exp.Arguments[0])} as nvarchar)";
 | 
					                    case "ToString":
 | 
				
			||||||
 | 
					                        var gentype = exp.Arguments[0].Type.NullableTypeOrThis();
 | 
				
			||||||
 | 
					                        return gentype == typeof(Guid) ?
 | 
				
			||||||
 | 
					                            $"cast({getExp(exp.Arguments[0])} as varchar(36))" :
 | 
				
			||||||
 | 
					                            $"cast({getExp(exp.Arguments[0])} as nvarchar{(gentype.IsNumberType() || gentype.IsEnum ? "(100)" : "(max)")})";
 | 
				
			||||||
                    case "ToUInt16": return $"cast({getExp(exp.Arguments[0])} as smallint)";
 | 
					                    case "ToUInt16": return $"cast({getExp(exp.Arguments[0])} as smallint)";
 | 
				
			||||||
                    case "ToUInt32": return $"cast({getExp(exp.Arguments[0])} as int)";
 | 
					                    case "ToUInt32": return $"cast({getExp(exp.Arguments[0])} as int)";
 | 
				
			||||||
                    case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as bigint)";
 | 
					                    case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as bigint)";
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,7 +36,9 @@ namespace FreeSql.SqlServer
 | 
				
			|||||||
                            case "System.Int64": return $"cast({getExp(operandExp)} as bigint)";
 | 
					                            case "System.Int64": return $"cast({getExp(operandExp)} as bigint)";
 | 
				
			||||||
                            case "System.SByte": return $"cast({getExp(operandExp)} as tinyint)";
 | 
					                            case "System.SByte": return $"cast({getExp(operandExp)} as tinyint)";
 | 
				
			||||||
                            case "System.Single": return $"cast({getExp(operandExp)} as decimal(14,7))";
 | 
					                            case "System.Single": return $"cast({getExp(operandExp)} as decimal(14,7))";
 | 
				
			||||||
                            case "System.String": return operandExp.Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(operandExp)} as varchar(36))" : $"cast({getExp(operandExp)} as nvarchar)";
 | 
					                            case "System.String": return gentype == typeof(Guid) ? 
 | 
				
			||||||
 | 
					                                    $"cast({getExp(operandExp)} as varchar(36))" : 
 | 
				
			||||||
 | 
					                                    $"cast({getExp(operandExp)} as nvarchar{(gentype.IsNumberType() || gentype.IsEnum ? "(100)" : "(max)")})";
 | 
				
			||||||
                            case "System.UInt16": return $"cast({getExp(operandExp)} as smallint)";
 | 
					                            case "System.UInt16": return $"cast({getExp(operandExp)} as smallint)";
 | 
				
			||||||
                            case "System.UInt32": return $"cast({getExp(operandExp)} as int)";
 | 
					                            case "System.UInt32": return $"cast({getExp(operandExp)} as int)";
 | 
				
			||||||
                            case "System.UInt64": return $"cast({getExp(operandExp)} as bigint)";
 | 
					                            case "System.UInt64": return $"cast({getExp(operandExp)} as bigint)";
 | 
				
			||||||
@@ -86,7 +88,10 @@ namespace FreeSql.SqlServer
 | 
				
			|||||||
                            if (callExp.Method.DeclaringType.IsNumberType()) return "rand()";
 | 
					                            if (callExp.Method.DeclaringType.IsNumberType()) return "rand()";
 | 
				
			||||||
                            return null;
 | 
					                            return null;
 | 
				
			||||||
                        case "ToString":
 | 
					                        case "ToString":
 | 
				
			||||||
                            if (callExp.Object != null) return callExp.Arguments.Count == 0 ? (callExp.Object.Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(callExp.Object)} as varchar(36))" : $"cast({getExp(callExp.Object)} as nvarchar)") : null;
 | 
					                            var gentype2 = callExp.Object.Type.NullableTypeOrThis();
 | 
				
			||||||
 | 
					                            if (callExp.Object != null) return callExp.Arguments.Count == 0 ? (gentype2 == typeof(Guid) ? 
 | 
				
			||||||
 | 
					                                    $"cast({getExp(callExp.Object)} as varchar(36))" : 
 | 
				
			||||||
 | 
					                                    $"cast({getExp(callExp.Object)} as nvarchar{(gentype2.IsNumberType() || gentype2.IsEnum ? "(100)" : "(max)")})") : null;
 | 
				
			||||||
                            return null;
 | 
					                            return null;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -262,10 +267,10 @@ namespace FreeSql.SqlServer
 | 
				
			|||||||
                    case "Contains":
 | 
					                    case "Contains":
 | 
				
			||||||
                        var args0Value = getExp(exp.Arguments[0]);
 | 
					                        var args0Value = getExp(exp.Arguments[0]);
 | 
				
			||||||
                        if (args0Value == "NULL") return $"({left}) IS NULL";
 | 
					                        if (args0Value == "NULL") return $"({left}) IS NULL";
 | 
				
			||||||
                        if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(cast({args0Value} as nvarchar)+'%')")}";
 | 
					                        if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(cast({args0Value} as nvarchar(max))+'%')")}";
 | 
				
			||||||
                        if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%'+cast({args0Value} as nvarchar))")}";
 | 
					                        if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%'+cast({args0Value} as nvarchar(max)))")}";
 | 
				
			||||||
                        if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}";
 | 
					                        if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}";
 | 
				
			||||||
                        return $"({left}) LIKE ('%'+cast({args0Value} as nvarchar)+'%')";
 | 
					                        return $"({left}) LIKE ('%'+cast({args0Value} as nvarchar(max))+'%')";
 | 
				
			||||||
                    case "ToLower": return $"lower({left})";
 | 
					                    case "ToLower": return $"lower({left})";
 | 
				
			||||||
                    case "ToUpper": return $"upper({left})";
 | 
					                    case "ToUpper": return $"upper({left})";
 | 
				
			||||||
                    case "Substring":
 | 
					                    case "Substring":
 | 
				
			||||||
@@ -336,7 +341,7 @@ namespace FreeSql.SqlServer
 | 
				
			|||||||
                switch (exp.Method.Name)
 | 
					                switch (exp.Method.Name)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    case "Compare": return $"({getExp(exp.Arguments[0])} - ({getExp(exp.Arguments[1])}))";
 | 
					                    case "Compare": return $"({getExp(exp.Arguments[0])} - ({getExp(exp.Arguments[1])}))";
 | 
				
			||||||
                    case "DaysInMonth": return $"datepart(day, dateadd(day, -1, dateadd(month, 1, cast({getExp(exp.Arguments[0])} as varchar) + '-' + cast({getExp(exp.Arguments[1])} as varchar) + '-1')))";
 | 
					                    case "DaysInMonth": return $"datepart(day, dateadd(day, -1, dateadd(month, 1, cast({getExp(exp.Arguments[0])} as varchar(100)) + '-' + cast({getExp(exp.Arguments[1])} as varchar(100)) + '-1')))";
 | 
				
			||||||
                    case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})";
 | 
					                    case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    case "IsLeapYear":
 | 
					                    case "IsLeapYear":
 | 
				
			||||||
@@ -452,7 +457,7 @@ namespace FreeSql.SqlServer
 | 
				
			|||||||
                    case "Subtract": return $"({left}-({args1}))";
 | 
					                    case "Subtract": return $"({left}-({args1}))";
 | 
				
			||||||
                    case "Equals": return $"({left} = {args1})";
 | 
					                    case "Equals": return $"({left} = {args1})";
 | 
				
			||||||
                    case "CompareTo": return $"({left}-({args1}))";
 | 
					                    case "CompareTo": return $"({left}-({args1}))";
 | 
				
			||||||
                    case "ToString": return $"cast({left} as varchar)";
 | 
					                    case "ToString": return $"cast({left} as varchar(100))";
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            return null;
 | 
					            return null;
 | 
				
			||||||
@@ -475,7 +480,11 @@ namespace FreeSql.SqlServer
 | 
				
			|||||||
                    case "ToInt64": return $"cast({getExp(exp.Arguments[0])} as bigint)";
 | 
					                    case "ToInt64": return $"cast({getExp(exp.Arguments[0])} as bigint)";
 | 
				
			||||||
                    case "ToSByte": return $"cast({getExp(exp.Arguments[0])} as tinyint)";
 | 
					                    case "ToSByte": return $"cast({getExp(exp.Arguments[0])} as tinyint)";
 | 
				
			||||||
                    case "ToSingle": return $"cast({getExp(exp.Arguments[0])} as decimal(14,7))";
 | 
					                    case "ToSingle": return $"cast({getExp(exp.Arguments[0])} as decimal(14,7))";
 | 
				
			||||||
                    case "ToString": return exp.Arguments[0].Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(exp.Arguments[0])} as varchar(36))" : $"cast({getExp(exp.Arguments[0])} as nvarchar)";
 | 
					                    case "ToString":
 | 
				
			||||||
 | 
					                        var gentype = exp.Arguments[0].Type.NullableTypeOrThis();
 | 
				
			||||||
 | 
					                        return gentype == typeof(Guid) ? 
 | 
				
			||||||
 | 
					                            $"cast({getExp(exp.Arguments[0])} as varchar(36))" : 
 | 
				
			||||||
 | 
					                            $"cast({getExp(exp.Arguments[0])} as nvarchar{(gentype.IsNumberType() || gentype.IsEnum ? "(100)" : "(max)")})";
 | 
				
			||||||
                    case "ToUInt16": return $"cast({getExp(exp.Arguments[0])} as smallint)";
 | 
					                    case "ToUInt16": return $"cast({getExp(exp.Arguments[0])} as smallint)";
 | 
				
			||||||
                    case "ToUInt32": return $"cast({getExp(exp.Arguments[0])} as int)";
 | 
					                    case "ToUInt32": return $"cast({getExp(exp.Arguments[0])} as int)";
 | 
				
			||||||
                    case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as bigint)";
 | 
					                    case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as bigint)";
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user