diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/Internal/FbQuerySqlGenerator.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/Internal/FbQuerySqlGenerator.cs index 17fb2ff6..388ed8c1 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/Internal/FbQuerySqlGenerator.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/Internal/FbQuerySqlGenerator.cs @@ -169,8 +169,11 @@ protected override Expression VisitSqlParameter(SqlParameterExpression sqlParame Sql.Append(" AS "); if (sqlParameterExpression.Type == typeof(string)) { + var storeTypeNameBase = sqlParameterExpression.TypeMapping.StoreTypeNameBase; + var size = sqlParameterExpression.TypeMapping.Size; var isUnicode = FbTypeMappingSource.IsUnicode(sqlParameterExpression.TypeMapping); - Sql.Append(((IFbSqlGenerationHelper)Dependencies.SqlGenerationHelper).StringParameterQueryType(isUnicode)); + + Sql.Append(((IFbSqlGenerationHelper)Dependencies.SqlGenerationHelper).StringParameterQueryType(isUnicode, storeTypeNameBase, size)); } else { @@ -191,9 +194,16 @@ protected override Expression VisitSqlConstant(SqlConstantExpression sqlConstant base.VisitSqlConstant(sqlConstantExpression); if (shouldExplicitStringLiteralTypes) { - var isUnicode = FbTypeMappingSource.IsUnicode(sqlConstantExpression.TypeMapping); + var storeTypeNameBase = sqlConstantExpression.TypeMapping.StoreTypeNameBase; + var size = sqlConstantExpression.TypeMapping.Size; + var isUnicode = FbTypeMappingSource.IsUnicode(sqlConstantExpression.TypeMapping); + Sql.Append(" AS "); - Sql.Append(((IFbSqlGenerationHelper)Dependencies.SqlGenerationHelper).StringLiteralQueryType(sqlConstantExpression.Value as string, isUnicode)); + Sql.Append(((IFbSqlGenerationHelper)Dependencies.SqlGenerationHelper).StringLiteralQueryType( + sqlConstantExpression.Value as string, + isUnicode, + storeTypeNameBase, + size)); Sql.Append(")"); } return sqlConstantExpression; diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird/Storage/Internal/FbSqlGenerationHelper.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird/Storage/Internal/FbSqlGenerationHelper.cs index 78bbff57..ead4bb4d 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird/Storage/Internal/FbSqlGenerationHelper.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird/Storage/Internal/FbSqlGenerationHelper.cs @@ -27,17 +27,38 @@ public FbSqlGenerationHelper(RelationalSqlGenerationHelperDependencies dependenc : base(dependencies) { } - public virtual string StringLiteralQueryType(string s, bool isUnicode = true) + public virtual string StringLiteralQueryType(string s, bool isUnicode = true, string storeTypeNameBase = "", int size = 0) { - var length = MinimumStringQueryTypeLength(s); + var maxSize = MinimumStringQueryTypeLength(s); + string typeName; + if (storeTypeNameBase.Equals("BLOB SUB_TYPE TEXT", StringComparison.OrdinalIgnoreCase)) + { + typeName = "VARCHAR"; + } + else + { + typeName = IsEmpty(storeTypeNameBase) ? "VARCHAR" : storeTypeNameBase; + } + var charset = isUnicode ? " CHARACTER SET UTF8" : string.Empty; - return $"VARCHAR({length}){charset}"; + return $"{typeName}({maxSize}){charset}"; } - public virtual string StringParameterQueryType(bool isUnicode) + public virtual string StringParameterQueryType(bool isUnicode, string storeTypeNameBase = "", int size = 0) { - var size = isUnicode ? FbTypeMappingSource.UnicodeVarcharMaxSize : FbTypeMappingSource.VarcharMaxSize; - return $"VARCHAR({size})"; + int maxSize; + string typeName; + if (storeTypeNameBase.Equals("BLOB SUB_TYPE TEXT", StringComparison.OrdinalIgnoreCase)) + { + maxSize = (isUnicode ? FbTypeMappingSource.UnicodeVarcharMaxSize : FbTypeMappingSource.VarcharMaxSize); + typeName = "VARCHAR"; + } + else + { + maxSize = size > 0 ? size : (isUnicode ? FbTypeMappingSource.UnicodeVarcharMaxSize : FbTypeMappingSource.VarcharMaxSize); + typeName = IsEmpty(storeTypeNameBase) ? "VARCHAR" : storeTypeNameBase; + } + return $"{typeName}({maxSize})"; } public virtual void GenerateBlockParameterName(StringBuilder builder, string name) @@ -47,7 +68,7 @@ public virtual void GenerateBlockParameterName(StringBuilder builder, string nam public virtual string AlternativeStatementTerminator => "~"; - static int MinimumStringQueryTypeLength(string s) + private int MinimumStringQueryTypeLength(string s) { var length = s?.Length ?? 0; if (length == 0) @@ -55,9 +76,8 @@ static int MinimumStringQueryTypeLength(string s) return length; } - static void EnsureStringLiteralQueryTypeLength(int length) + private bool IsEmpty(string storeTypeNameBase) { - if (length > FbTypeMappingSource.UnicodeVarcharMaxSize) - throw new ArgumentOutOfRangeException(nameof(length)); + return (storeTypeNameBase == null || string.IsNullOrEmpty(storeTypeNameBase) || string.IsNullOrWhiteSpace(storeTypeNameBase)); } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird/Storage/Internal/IFbSqlGenerationHelper.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird/Storage/Internal/IFbSqlGenerationHelper.cs index 56c4c1f5..bb6af11c 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird/Storage/Internal/IFbSqlGenerationHelper.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird/Storage/Internal/IFbSqlGenerationHelper.cs @@ -22,8 +22,8 @@ namespace FirebirdSql.EntityFrameworkCore.Firebird.Storage.Internal; public interface IFbSqlGenerationHelper : ISqlGenerationHelper { - string StringLiteralQueryType(string s, bool isUnicode); - string StringParameterQueryType(bool isUnicode); + string StringLiteralQueryType(string s, bool isUnicode, string storeTypeNameBase = "", int size = 0); + string StringParameterQueryType(bool isUnicode, string storeTypeNameBase = "", int size = 0); void GenerateBlockParameterName(StringBuilder builder, string name); string AlternativeStatementTerminator { get; } }