From a2db5066e147d994d08c4adf2b9dade9991110cc Mon Sep 17 00:00:00 2001 From: Christopher Jolly Date: Sat, 8 Apr 2023 08:51:48 +0800 Subject: [PATCH] The object tostring translator was doing it on the server. It needs to be handled on the client to get the actual name of the enum rather than its int value Also handles the boolean special cases --- .../Internal/JetObjectToStringTranslator.cs | 90 +++++++++++++------ 1 file changed, 61 insertions(+), 29 deletions(-) diff --git a/src/EFCore.Jet/Query/ExpressionTranslators/Internal/JetObjectToStringTranslator.cs b/src/EFCore.Jet/Query/ExpressionTranslators/Internal/JetObjectToStringTranslator.cs index 43d17d4..961cc9e 100644 --- a/src/EFCore.Jet/Query/ExpressionTranslators/Internal/JetObjectToStringTranslator.cs +++ b/src/EFCore.Jet/Query/ExpressionTranslators/Internal/JetObjectToStringTranslator.cs @@ -19,40 +19,72 @@ namespace EntityFrameworkCore.Jet.Query.ExpressionTranslators.Internal { private readonly JetSqlExpressionFactory _sqlExpressionFactory; - private static readonly Type[] _typeMapping = - { - typeof(int), - typeof(long), - typeof(DateTime), - typeof(Guid), - typeof(bool), - typeof(byte), - typeof(byte[]), - typeof(double), - typeof(DateTimeOffset), - typeof(char), - typeof(short), - typeof(float), - typeof(decimal), - typeof(TimeSpan), - typeof(uint), - typeof(ushort), - typeof(ulong), - typeof(sbyte), - }; + private const int DefaultLength = 100; + + private static readonly Dictionary TypeMapping + = new() + { + { typeof(sbyte), "varchar(4)" }, + { typeof(byte), "varchar(3)" }, + { typeof(short), "varchar(6)" }, + { typeof(ushort), "varchar(5)" }, + { typeof(int), "varchar(11)" }, + { typeof(uint), "varchar(10)" }, + { typeof(long), "varchar(20)" }, + { typeof(ulong), "varchar(20)" }, + { typeof(float), $"varchar({DefaultLength})" }, + { typeof(double), $"varchar({DefaultLength})" }, + { typeof(decimal), $"varchar({DefaultLength})" }, + { typeof(char), "varchar(1)" }, + { typeof(DateTime), $"varchar({DefaultLength})" }, + { typeof(DateTimeOffset), $"varchar({DefaultLength})" }, + { typeof(TimeSpan), $"varchar({DefaultLength})" }, + { typeof(Guid), "varchar(36)" }, + { typeof(byte[]), $"varchar({DefaultLength})" } + }; public JetObjectToStringTranslator(SqlExpressionFactory sqlExpressionFactory) => _sqlExpressionFactory = (JetSqlExpressionFactory)sqlExpressionFactory; - public SqlExpression? Translate(SqlExpression? instance, MethodInfo method, IReadOnlyList arguments, IDiagnosticsLogger logger) + public virtual SqlExpression? Translate( + SqlExpression? instance, + MethodInfo method, + IReadOnlyList arguments, + IDiagnosticsLogger logger) { - return method.Name == nameof(ToString) - && arguments.Count == 0 - && instance != null - && _typeMapping.Contains( - instance.Type - .UnwrapNullableType() - .UnwrapEnumType()) + if (instance == null || method.Name != nameof(ToString) || arguments.Count != 0) + { + return null; + } + + if (instance.Type == typeof(bool)) + { + if (instance is ColumnExpression columnExpression && columnExpression.IsNullable) + { + return _sqlExpressionFactory.Case( + new[] + { + new CaseWhenClause( + _sqlExpressionFactory.Equal(instance, _sqlExpressionFactory.Constant(false)), + _sqlExpressionFactory.Constant(false.ToString())), + new CaseWhenClause( + _sqlExpressionFactory.Equal(instance, _sqlExpressionFactory.Constant(true)), + _sqlExpressionFactory.Constant(true.ToString())) + }, + _sqlExpressionFactory.Constant(null)); + } + + return _sqlExpressionFactory.Case( + new[] + { + new CaseWhenClause( + _sqlExpressionFactory.Equal(instance, _sqlExpressionFactory.Constant(false)), + _sqlExpressionFactory.Constant(false.ToString())) + }, + _sqlExpressionFactory.Constant(true.ToString())); + } + + return TypeMapping.TryGetValue(instance.Type, out var storeType) ? _sqlExpressionFactory.Convert(instance, typeof(string)) : null; }