From 3e376ff10644a9a1b926d04bbc2b378a0047ad42 Mon Sep 17 00:00:00 2001 From: Christopher Jolly Date: Sat, 1 Apr 2023 22:39:34 +0800 Subject: [PATCH] Fix byte array stuff --- .../Internal/JetByteArrayMethodTranslator.cs | 82 +++++ .../JetMethodCallTranslatorProvider.cs | 3 +- .../Storage/Internal/JetTypeMappingSource.cs | 26 +- .../EverythingIsBytesJetTest.cs | 291 ++++++++++-------- 4 files changed, 258 insertions(+), 144 deletions(-) create mode 100644 src/EFCore.Jet/Query/ExpressionTranslators/Internal/JetByteArrayMethodTranslator.cs diff --git a/src/EFCore.Jet/Query/ExpressionTranslators/Internal/JetByteArrayMethodTranslator.cs b/src/EFCore.Jet/Query/ExpressionTranslators/Internal/JetByteArrayMethodTranslator.cs new file mode 100644 index 0000000..b81a2cb --- /dev/null +++ b/src/EFCore.Jet/Query/ExpressionTranslators/Internal/JetByteArrayMethodTranslator.cs @@ -0,0 +1,82 @@ +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.EntityFrameworkCore.Query; +using Microsoft.EntityFrameworkCore.Query.SqlExpressions; + +namespace EntityFrameworkCore.Jet.Query.ExpressionTranslators.Internal; + +/// +/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to +/// the same compatibility standards as public APIs. It may be changed or removed without notice in +/// any release. You should only use it directly in your code with extreme caution and knowing that +/// doing so can result in application failures when updating to a new Entity Framework Core release. +/// +public class JetByteArrayMethodTranslator : IMethodCallTranslator +{ + private readonly ISqlExpressionFactory _sqlExpressionFactory; + + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + public JetByteArrayMethodTranslator(ISqlExpressionFactory sqlExpressionFactory) + { + _sqlExpressionFactory = sqlExpressionFactory; + } + + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + public virtual SqlExpression? Translate( + SqlExpression? instance, + MethodInfo method, + IReadOnlyList arguments, + IDiagnosticsLogger logger) + { + if (method is { IsGenericMethod: true, Name: nameof(Enumerable.Contains) } + && arguments[0].Type == typeof(byte[])) + { + var source = arguments[0]; + var sourceTypeMapping = source.TypeMapping; + + var value = arguments[1] is SqlConstantExpression constantValue + ? (SqlExpression)_sqlExpressionFactory.Constant(new[] { (byte)constantValue.Value! }, sourceTypeMapping) + : _sqlExpressionFactory.Convert(arguments[1], typeof(byte[]), sourceTypeMapping); + + return _sqlExpressionFactory.GreaterThan( + _sqlExpressionFactory.Function( + "INSTR", + new[] { _sqlExpressionFactory.Constant(1), source, value, _sqlExpressionFactory.Constant(1) }, + nullable: true, + argumentsPropagateNullability: new[] { true, true }, + typeof(int)), + _sqlExpressionFactory.Constant(0)); + } + + if (method is { IsGenericMethod: true, Name: nameof(Enumerable.First) } && method.GetParameters().Length == 1 + && arguments[0].Type == typeof(byte[])) + { + return _sqlExpressionFactory.Convert( + _sqlExpressionFactory.Function( + "MID", + new[] { arguments[0], _sqlExpressionFactory.Constant(1), _sqlExpressionFactory.Constant(1) }, + nullable: true, + argumentsPropagateNullability: new[] { true, true, true }, + typeof(byte[])), + method.ReturnType); + } + + return null; + } +} diff --git a/src/EFCore.Jet/Query/ExpressionTranslators/Internal/JetMethodCallTranslatorProvider.cs b/src/EFCore.Jet/Query/ExpressionTranslators/Internal/JetMethodCallTranslatorProvider.cs index b750bc9..5096512 100644 --- a/src/EFCore.Jet/Query/ExpressionTranslators/Internal/JetMethodCallTranslatorProvider.cs +++ b/src/EFCore.Jet/Query/ExpressionTranslators/Internal/JetMethodCallTranslatorProvider.cs @@ -19,12 +19,13 @@ namespace EntityFrameworkCore.Jet.Query.ExpressionTranslators.Internal [NotNull] RelationalMethodCallTranslatorProviderDependencies dependencies) : base(dependencies) { - var sqlExpressionFactory = (JetSqlExpressionFactory) dependencies.SqlExpressionFactory; + var sqlExpressionFactory = (JetSqlExpressionFactory)dependencies.SqlExpressionFactory; // ReSharper disable once VirtualMemberCallInConstructor AddTranslators( new IMethodCallTranslator[] { + new JetByteArrayMethodTranslator(sqlExpressionFactory), new JetConvertTranslator(sqlExpressionFactory), new JetDateDiffFunctionsTranslator(sqlExpressionFactory), new JetDateTimeMethodTranslator(sqlExpressionFactory), diff --git a/src/EFCore.Jet/Storage/Internal/JetTypeMappingSource.cs b/src/EFCore.Jet/Storage/Internal/JetTypeMappingSource.cs index b0600e0..f32be6d 100644 --- a/src/EFCore.Jet/Storage/Internal/JetTypeMappingSource.cs +++ b/src/EFCore.Jet/Storage/Internal/JetTypeMappingSource.cs @@ -1,12 +1,14 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Collections; using System.Collections.Generic; using System.Data; using System.Linq; using EntityFrameworkCore.Jet.Infrastructure.Internal; using EntityFrameworkCore.Jet.Internal; using JetBrains.Annotations; +using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Storage; @@ -29,7 +31,7 @@ namespace EntityFrameworkCore.Jet.Storage.Internal // We just map counter etc. to integer. Whether an integer property/column is actually a counter // is determined by the value generation type. private readonly IntTypeMapping _counter = new JetIntTypeMapping("integer"); - + private readonly ByteTypeMapping _byte = new ByteTypeMapping("byte", DbType.Byte); // unsigned, there is no signed byte in Jet private readonly ShortTypeMapping _smallint = new ShortTypeMapping("smallint", DbType.Int16); private readonly IntTypeMapping _integer = new JetIntTypeMapping("integer"); @@ -52,7 +54,11 @@ namespace EntityFrameworkCore.Jet.Storage.Internal private readonly JetStringTypeMapping _unboundedUnicodeString = new JetStringTypeMapping("longchar", unicode: true, storeTypePostfix: StoreTypePostfix.None); private readonly GuidTypeMapping _guid = new GuidTypeMapping("uniqueidentifier", DbType.Guid); - private readonly JetByteArrayTypeMapping _rowversion = new JetByteArrayTypeMapping("varbinary", size: 8); + private readonly JetByteArrayTypeMapping _rowversion = new JetByteArrayTypeMapping("varbinary", size: 8, + comparer: new ValueComparer( + (v1, v2) => StructuralComparisons.StructuralEqualityComparer.Equals(v1, v2), + v => StructuralComparisons.StructuralEqualityComparer.GetHashCode(v), + v => v.ToArray())); private readonly Dictionary _storeTypeMappings; private readonly Dictionary _clrTypeMappings; @@ -76,7 +82,7 @@ namespace EntityFrameworkCore.Jet.Storage.Internal // TODO: Check the types and their mappings against // https://docs.microsoft.com/en-us/previous-versions/office/developer/office2000/aa140015(v=office.10) - + _datetime = new JetDateTimeTypeMapping("datetime", options, dbType: DbType.DateTime); _datetimeoffset = new JetDateTimeOffsetTypeMapping("datetime", options); _date = new JetDateTimeTypeMapping("datetime", options, dbType: DbType.Date); @@ -102,11 +108,11 @@ namespace EntityFrameworkCore.Jet.Storage.Internal {"logical", _bit}, {"logical1", _bit}, {"yesno", _bit}, - + {"counter", _counter}, {"identity", _counter}, {"autoincrement", _counter}, - + {"byte", _byte}, {"tinyint", _byte}, {"integer1", _byte}, @@ -119,7 +125,7 @@ namespace EntityFrameworkCore.Jet.Storage.Internal {"long", _bigint}, {"int", _integer}, {"integer4", _integer}, - + {"single", _single}, {"real", _single}, {"float4", _single}, @@ -304,10 +310,10 @@ namespace EntityFrameworkCore.Jet.Storage.Internal const int maxCharColumnSize = 255; const int maxIndexedCharColumnSize = 255; - var size = mappingInfo.Size ?? (mappingInfo.IsKeyOrIndex ? (int?) maxIndexedCharColumnSize : null); + var size = mappingInfo.Size ?? (mappingInfo.IsKeyOrIndex ? (int?)maxIndexedCharColumnSize : null); if (size > maxCharColumnSize) { - size = isFixedLength ? maxCharColumnSize : (int?) null; + size = isFixedLength ? maxCharColumnSize : (int?)null; } return size == null @@ -331,10 +337,10 @@ namespace EntityFrameworkCore.Jet.Storage.Internal const int maxBinaryColumnSize = 510; - var size = mappingInfo.Size ?? (mappingInfo.IsKeyOrIndex ? (int?) maxBinaryColumnSize : null); + var size = mappingInfo.Size ?? (mappingInfo.IsKeyOrIndex ? (int?)maxBinaryColumnSize : null); if (size > maxBinaryColumnSize) { - size = isFixedLength ? maxBinaryColumnSize : (int?) null; + size = isFixedLength ? maxBinaryColumnSize : (int?)null; } return size == null diff --git a/test/EFCore.Jet.FunctionalTests/EverythingIsBytesJetTest.cs b/test/EFCore.Jet.FunctionalTests/EverythingIsBytesJetTest.cs index a3b5491..0f04dc1 100644 --- a/test/EFCore.Jet.FunctionalTests/EverythingIsBytesJetTest.cs +++ b/test/EFCore.Jet.FunctionalTests/EverythingIsBytesJetTest.cs @@ -32,138 +32,139 @@ namespace EntityFrameworkCore.Jet.FunctionalTests nameof(NonNullableBackedDataTypes), nameof(AnimalDetails)); - const string expected = @"Animal.Id ---> `varbinary` [MaxLength = 4] -AnimalIdentification.AnimalId ---> `varbinary` [MaxLength = 4] -AnimalIdentification.Id ---> `varbinary` [MaxLength = 4] -AnimalIdentification.Method ---> `varbinary` [MaxLength = 4] -BinaryForeignKeyDataType.BinaryKeyDataTypeId ---> `nullable varbinary` [MaxLength = 900] -BinaryForeignKeyDataType.Id ---> `varbinary` [MaxLength = 4] -BinaryKeyDataType.Ex ---> `nullable varbinary` [MaxLength = -1] -BinaryKeyDataType.Id ---> `varbinary` [MaxLength = 900] -BuiltInDataTypes.Enum16 ---> `varbinary` [MaxLength = 2] -BuiltInDataTypes.Enum32 ---> `varbinary` [MaxLength = 4] -BuiltInDataTypes.Enum64 ---> `varbinary` [MaxLength = 8] -BuiltInDataTypes.Enum8 ---> `varbinary` [MaxLength = 1] -BuiltInDataTypes.EnumS8 ---> `varbinary` [MaxLength = 1] -BuiltInDataTypes.EnumU16 ---> `varbinary` [MaxLength = 2] -BuiltInDataTypes.EnumU32 ---> `varbinary` [MaxLength = 4] -BuiltInDataTypes.EnumU64 ---> `varbinary` [MaxLength = 8] -BuiltInDataTypes.Id ---> `varbinary` [MaxLength = 4] -BuiltInDataTypes.PartitionId ---> `varbinary` [MaxLength = 4] -BuiltInDataTypes.TestBoolean ---> `varbinary` [MaxLength = 1] -BuiltInDataTypes.TestByte ---> `varbinary` [MaxLength = 1] -BuiltInDataTypes.TestCharacter ---> `varbinary` [MaxLength = 2] -BuiltInDataTypes.TestDateTime ---> `varbinary` [MaxLength = 8] -BuiltInDataTypes.TestDateTimeOffset ---> `varbinary` [MaxLength = 12] -BuiltInDataTypes.TestDecimal ---> `varbinary` [MaxLength = 16] -BuiltInDataTypes.TestDouble ---> `varbinary` [MaxLength = 8] -BuiltInDataTypes.TestInt16 ---> `varbinary` [MaxLength = 2] -BuiltInDataTypes.TestInt32 ---> `varbinary` [MaxLength = 4] -BuiltInDataTypes.TestInt64 ---> `varbinary` [MaxLength = 8] -BuiltInDataTypes.TestSignedByte ---> `varbinary` [MaxLength = 1] -BuiltInDataTypes.TestSingle ---> `varbinary` [MaxLength = 4] -BuiltInDataTypes.TestTimeSpan ---> `varbinary` [MaxLength = 8] -BuiltInDataTypes.TestUnsignedInt16 ---> `varbinary` [MaxLength = 2] -BuiltInDataTypes.TestUnsignedInt32 ---> `varbinary` [MaxLength = 4] -BuiltInDataTypes.TestUnsignedInt64 ---> `varbinary` [MaxLength = 8] -BuiltInDataTypesShadow.Enum16 ---> `varbinary` [MaxLength = 2] -BuiltInDataTypesShadow.Enum32 ---> `varbinary` [MaxLength = 4] -BuiltInDataTypesShadow.Enum64 ---> `varbinary` [MaxLength = 8] -BuiltInDataTypesShadow.Enum8 ---> `varbinary` [MaxLength = 1] -BuiltInDataTypesShadow.EnumS8 ---> `varbinary` [MaxLength = 1] -BuiltInDataTypesShadow.EnumU16 ---> `varbinary` [MaxLength = 2] -BuiltInDataTypesShadow.EnumU32 ---> `varbinary` [MaxLength = 4] -BuiltInDataTypesShadow.EnumU64 ---> `varbinary` [MaxLength = 8] -BuiltInDataTypesShadow.Id ---> `varbinary` [MaxLength = 4] -BuiltInDataTypesShadow.PartitionId ---> `varbinary` [MaxLength = 4] -BuiltInDataTypesShadow.TestBoolean ---> `varbinary` [MaxLength = 1] -BuiltInDataTypesShadow.TestByte ---> `varbinary` [MaxLength = 1] -BuiltInDataTypesShadow.TestCharacter ---> `varbinary` [MaxLength = 2] -BuiltInDataTypesShadow.TestDateTime ---> `varbinary` [MaxLength = 8] -BuiltInDataTypesShadow.TestDateTimeOffset ---> `varbinary` [MaxLength = 12] -BuiltInDataTypesShadow.TestDecimal ---> `varbinary` [MaxLength = 16] -BuiltInDataTypesShadow.TestDouble ---> `varbinary` [MaxLength = 8] -BuiltInDataTypesShadow.TestInt16 ---> `varbinary` [MaxLength = 2] -BuiltInDataTypesShadow.TestInt32 ---> `varbinary` [MaxLength = 4] -BuiltInDataTypesShadow.TestInt64 ---> `varbinary` [MaxLength = 8] -BuiltInDataTypesShadow.TestSignedByte ---> `varbinary` [MaxLength = 1] -BuiltInDataTypesShadow.TestSingle ---> `varbinary` [MaxLength = 4] -BuiltInDataTypesShadow.TestTimeSpan ---> `varbinary` [MaxLength = 8] -BuiltInDataTypesShadow.TestUnsignedInt16 ---> `varbinary` [MaxLength = 2] -BuiltInDataTypesShadow.TestUnsignedInt32 ---> `varbinary` [MaxLength = 4] -BuiltInDataTypesShadow.TestUnsignedInt64 ---> `varbinary` [MaxLength = 8] -BuiltInNullableDataTypes.Enum16 ---> `nullable varbinary` [MaxLength = 2] -BuiltInNullableDataTypes.Enum32 ---> `nullable varbinary` [MaxLength = 4] -BuiltInNullableDataTypes.Enum64 ---> `nullable varbinary` [MaxLength = 8] -BuiltInNullableDataTypes.Enum8 ---> `nullable varbinary` [MaxLength = 1] -BuiltInNullableDataTypes.EnumS8 ---> `nullable varbinary` [MaxLength = 1] -BuiltInNullableDataTypes.EnumU16 ---> `nullable varbinary` [MaxLength = 2] -BuiltInNullableDataTypes.EnumU32 ---> `nullable varbinary` [MaxLength = 4] -BuiltInNullableDataTypes.EnumU64 ---> `nullable varbinary` [MaxLength = 8] -BuiltInNullableDataTypes.Id ---> `varbinary` [MaxLength = 4] -BuiltInNullableDataTypes.PartitionId ---> `varbinary` [MaxLength = 4] -BuiltInNullableDataTypes.TestByteArray ---> `nullable varbinary` [MaxLength = -1] -BuiltInNullableDataTypes.TestNullableBoolean ---> `nullable varbinary` [MaxLength = 1] -BuiltInNullableDataTypes.TestNullableByte ---> `nullable varbinary` [MaxLength = 1] -BuiltInNullableDataTypes.TestNullableCharacter ---> `nullable varbinary` [MaxLength = 2] -BuiltInNullableDataTypes.TestNullableDateTime ---> `nullable varbinary` [MaxLength = 8] -BuiltInNullableDataTypes.TestNullableDateTimeOffset ---> `nullable varbinary` [MaxLength = 12] -BuiltInNullableDataTypes.TestNullableDecimal ---> `nullable varbinary` [MaxLength = 16] -BuiltInNullableDataTypes.TestNullableDouble ---> `nullable varbinary` [MaxLength = 8] -BuiltInNullableDataTypes.TestNullableInt16 ---> `nullable varbinary` [MaxLength = 2] -BuiltInNullableDataTypes.TestNullableInt32 ---> `nullable varbinary` [MaxLength = 4] -BuiltInNullableDataTypes.TestNullableInt64 ---> `nullable varbinary` [MaxLength = 8] -BuiltInNullableDataTypes.TestNullableSignedByte ---> `nullable varbinary` [MaxLength = 1] -BuiltInNullableDataTypes.TestNullableSingle ---> `nullable varbinary` [MaxLength = 4] -BuiltInNullableDataTypes.TestNullableTimeSpan ---> `nullable varbinary` [MaxLength = 8] -BuiltInNullableDataTypes.TestNullableUnsignedInt16 ---> `nullable varbinary` [MaxLength = 2] -BuiltInNullableDataTypes.TestNullableUnsignedInt32 ---> `nullable varbinary` [MaxLength = 4] -BuiltInNullableDataTypes.TestNullableUnsignedInt64 ---> `nullable varbinary` [MaxLength = 8] -BuiltInNullableDataTypes.TestString ---> `nullable varbinary` [MaxLength = -1] -BuiltInNullableDataTypesShadow.Enum16 ---> `nullable varbinary` [MaxLength = 2] -BuiltInNullableDataTypesShadow.Enum32 ---> `nullable varbinary` [MaxLength = 4] -BuiltInNullableDataTypesShadow.Enum64 ---> `nullable varbinary` [MaxLength = 8] -BuiltInNullableDataTypesShadow.Enum8 ---> `nullable varbinary` [MaxLength = 1] -BuiltInNullableDataTypesShadow.EnumS8 ---> `nullable varbinary` [MaxLength = 1] -BuiltInNullableDataTypesShadow.EnumU16 ---> `nullable varbinary` [MaxLength = 2] -BuiltInNullableDataTypesShadow.EnumU32 ---> `nullable varbinary` [MaxLength = 4] -BuiltInNullableDataTypesShadow.EnumU64 ---> `nullable varbinary` [MaxLength = 8] -BuiltInNullableDataTypesShadow.Id ---> `varbinary` [MaxLength = 4] -BuiltInNullableDataTypesShadow.PartitionId ---> `varbinary` [MaxLength = 4] -BuiltInNullableDataTypesShadow.TestByteArray ---> `nullable varbinary` [MaxLength = -1] -BuiltInNullableDataTypesShadow.TestNullableBoolean ---> `nullable varbinary` [MaxLength = 1] -BuiltInNullableDataTypesShadow.TestNullableByte ---> `nullable varbinary` [MaxLength = 1] -BuiltInNullableDataTypesShadow.TestNullableCharacter ---> `nullable varbinary` [MaxLength = 2] -BuiltInNullableDataTypesShadow.TestNullableDateTime ---> `nullable varbinary` [MaxLength = 8] -BuiltInNullableDataTypesShadow.TestNullableDateTimeOffset ---> `nullable varbinary` [MaxLength = 12] -BuiltInNullableDataTypesShadow.TestNullableDecimal ---> `nullable varbinary` [MaxLength = 16] -BuiltInNullableDataTypesShadow.TestNullableDouble ---> `nullable varbinary` [MaxLength = 8] -BuiltInNullableDataTypesShadow.TestNullableInt16 ---> `nullable varbinary` [MaxLength = 2] -BuiltInNullableDataTypesShadow.TestNullableInt32 ---> `nullable varbinary` [MaxLength = 4] -BuiltInNullableDataTypesShadow.TestNullableInt64 ---> `nullable varbinary` [MaxLength = 8] -BuiltInNullableDataTypesShadow.TestNullableSignedByte ---> `nullable varbinary` [MaxLength = 1] -BuiltInNullableDataTypesShadow.TestNullableSingle ---> `nullable varbinary` [MaxLength = 4] -BuiltInNullableDataTypesShadow.TestNullableTimeSpan ---> `nullable varbinary` [MaxLength = 8] -BuiltInNullableDataTypesShadow.TestNullableUnsignedInt16 ---> `nullable varbinary` [MaxLength = 2] -BuiltInNullableDataTypesShadow.TestNullableUnsignedInt32 ---> `nullable varbinary` [MaxLength = 4] -BuiltInNullableDataTypesShadow.TestNullableUnsignedInt64 ---> `nullable varbinary` [MaxLength = 8] -BuiltInNullableDataTypesShadow.TestString ---> `nullable varbinary` [MaxLength = -1] -EmailTemplate.Id ---> `varbinary` [MaxLength = 16] -EmailTemplate.TemplateType ---> `varbinary` [MaxLength = 4] -MaxLengthDataTypes.ByteArray5 ---> `nullable varbinary` [MaxLength = 5] -MaxLengthDataTypes.ByteArray9000 ---> `nullable varbinary` [MaxLength = -1] -MaxLengthDataTypes.Id ---> `varbinary` [MaxLength = 4] -MaxLengthDataTypes.String3 ---> `nullable varbinary` [MaxLength = 3] -MaxLengthDataTypes.String9000 ---> `nullable varbinary` [MaxLength = -1] -StringForeignKeyDataType.Id ---> `varbinary` [MaxLength = 4] -StringForeignKeyDataType.StringKeyDataTypeId ---> `nullable varbinary` [MaxLength = 900] -StringKeyDataType.Id ---> `varbinary` [MaxLength = 900] -UnicodeDataTypes.Id ---> `varbinary` [MaxLength = 4] -UnicodeDataTypes.StringAnsi ---> `nullable varbinary` [MaxLength = -1] -UnicodeDataTypes.StringAnsi3 ---> `nullable varbinary` [MaxLength = 3] -UnicodeDataTypes.StringAnsi9000 ---> `nullable varbinary` [MaxLength = -1] -UnicodeDataTypes.StringDefault ---> `nullable varbinary` [MaxLength = -1] -UnicodeDataTypes.StringUnicode ---> `nullable varbinary` [MaxLength = -1] + const string expected = @"#Dual.ID ---> [integer] +BinaryForeignKeyDataType.BinaryKeyDataTypeId ---> [nullable varbinary] [MaxLength = 255] +BinaryForeignKeyDataType.Id ---> [varbinary] [MaxLength = 4] +BinaryKeyDataType.Ex ---> [nullable varbinary] [MaxLength = -1] +BinaryKeyDataType.Id ---> [varbinary] [MaxLength = 255] +BuiltInDataTypes.Enum16 ---> [varbinary] [MaxLength = 2] +BuiltInDataTypes.Enum32 ---> [varbinary] [MaxLength = 4] +BuiltInDataTypes.Enum64 ---> [varbinary] [MaxLength = 8] +BuiltInDataTypes.Enum8 ---> [varbinary] [MaxLength = 1] +BuiltInDataTypes.EnumS8 ---> [varbinary] [MaxLength = 1] +BuiltInDataTypes.EnumU16 ---> [varbinary] [MaxLength = 2] +BuiltInDataTypes.EnumU32 ---> [varbinary] [MaxLength = 4] +BuiltInDataTypes.EnumU64 ---> [varbinary] [MaxLength = 8] +BuiltInDataTypes.Id ---> [varbinary] [MaxLength = 4] +BuiltInDataTypes.PartitionId ---> [varbinary] [MaxLength = 4] +BuiltInDataTypes.TestBoolean ---> [varbinary] [MaxLength = 1] +BuiltInDataTypes.TestByte ---> [varbinary] [MaxLength = 1] +BuiltInDataTypes.TestCharacter ---> [varbinary] [MaxLength = 2] +BuiltInDataTypes.TestDateTime ---> [varbinary] [MaxLength = 8] +BuiltInDataTypes.TestDateTimeOffset ---> [varbinary] [MaxLength = 12] +BuiltInDataTypes.TestDecimal ---> [varbinary] [MaxLength = 16] +BuiltInDataTypes.TestDouble ---> [varbinary] [MaxLength = 8] +BuiltInDataTypes.TestInt16 ---> [varbinary] [MaxLength = 2] +BuiltInDataTypes.TestInt32 ---> [varbinary] [MaxLength = 4] +BuiltInDataTypes.TestInt64 ---> [varbinary] [MaxLength = 8] +BuiltInDataTypes.TestSignedByte ---> [varbinary] [MaxLength = 1] +BuiltInDataTypes.TestSingle ---> [varbinary] [MaxLength = 4] +BuiltInDataTypes.TestTimeSpan ---> [varbinary] [MaxLength = 8] +BuiltInDataTypes.TestUnsignedInt16 ---> [varbinary] [MaxLength = 2] +BuiltInDataTypes.TestUnsignedInt32 ---> [varbinary] [MaxLength = 4] +BuiltInDataTypes.TestUnsignedInt64 ---> [varbinary] [MaxLength = 8] +BuiltInDataTypesShadow.Enum16 ---> [varbinary] [MaxLength = 2] +BuiltInDataTypesShadow.Enum32 ---> [varbinary] [MaxLength = 4] +BuiltInDataTypesShadow.Enum64 ---> [varbinary] [MaxLength = 8] +BuiltInDataTypesShadow.Enum8 ---> [varbinary] [MaxLength = 1] +BuiltInDataTypesShadow.EnumS8 ---> [varbinary] [MaxLength = 1] +BuiltInDataTypesShadow.EnumU16 ---> [varbinary] [MaxLength = 2] +BuiltInDataTypesShadow.EnumU32 ---> [varbinary] [MaxLength = 4] +BuiltInDataTypesShadow.EnumU64 ---> [varbinary] [MaxLength = 8] +BuiltInDataTypesShadow.Id ---> [varbinary] [MaxLength = 4] +BuiltInDataTypesShadow.PartitionId ---> [varbinary] [MaxLength = 4] +BuiltInDataTypesShadow.TestBoolean ---> [varbinary] [MaxLength = 1] +BuiltInDataTypesShadow.TestByte ---> [varbinary] [MaxLength = 1] +BuiltInDataTypesShadow.TestCharacter ---> [varbinary] [MaxLength = 2] +BuiltInDataTypesShadow.TestDateTime ---> [varbinary] [MaxLength = 8] +BuiltInDataTypesShadow.TestDateTimeOffset ---> [varbinary] [MaxLength = 12] +BuiltInDataTypesShadow.TestDecimal ---> [varbinary] [MaxLength = 16] +BuiltInDataTypesShadow.TestDouble ---> [varbinary] [MaxLength = 8] +BuiltInDataTypesShadow.TestInt16 ---> [varbinary] [MaxLength = 2] +BuiltInDataTypesShadow.TestInt32 ---> [varbinary] [MaxLength = 4] +BuiltInDataTypesShadow.TestInt64 ---> [varbinary] [MaxLength = 8] +BuiltInDataTypesShadow.TestSignedByte ---> [varbinary] [MaxLength = 1] +BuiltInDataTypesShadow.TestSingle ---> [varbinary] [MaxLength = 4] +BuiltInDataTypesShadow.TestTimeSpan ---> [varbinary] [MaxLength = 8] +BuiltInDataTypesShadow.TestUnsignedInt16 ---> [varbinary] [MaxLength = 2] +BuiltInDataTypesShadow.TestUnsignedInt32 ---> [varbinary] [MaxLength = 4] +BuiltInDataTypesShadow.TestUnsignedInt64 ---> [varbinary] [MaxLength = 8] +BuiltInNullableDataTypes.Enum16 ---> [nullable varbinary] [MaxLength = 2] +BuiltInNullableDataTypes.Enum32 ---> [nullable varbinary] [MaxLength = 4] +BuiltInNullableDataTypes.Enum64 ---> [nullable varbinary] [MaxLength = 8] +BuiltInNullableDataTypes.Enum8 ---> [nullable varbinary] [MaxLength = 1] +BuiltInNullableDataTypes.EnumS8 ---> [nullable varbinary] [MaxLength = 1] +BuiltInNullableDataTypes.EnumU16 ---> [nullable varbinary] [MaxLength = 2] +BuiltInNullableDataTypes.EnumU32 ---> [nullable varbinary] [MaxLength = 4] +BuiltInNullableDataTypes.EnumU64 ---> [nullable varbinary] [MaxLength = 8] +BuiltInNullableDataTypes.Id ---> [varbinary] [MaxLength = 4] +BuiltInNullableDataTypes.PartitionId ---> [varbinary] [MaxLength = 4] +BuiltInNullableDataTypes.TestByteArray ---> [nullable varbinary] [MaxLength = -1] +BuiltInNullableDataTypes.TestNullableBoolean ---> [nullable varbinary] [MaxLength = 1] +BuiltInNullableDataTypes.TestNullableByte ---> [nullable varbinary] [MaxLength = 1] +BuiltInNullableDataTypes.TestNullableCharacter ---> [nullable varbinary] [MaxLength = 2] +BuiltInNullableDataTypes.TestNullableDateTime ---> [nullable varbinary] [MaxLength = 8] +BuiltInNullableDataTypes.TestNullableDateTimeOffset ---> [nullable varbinary] [MaxLength = 12] +BuiltInNullableDataTypes.TestNullableDecimal ---> [nullable varbinary] [MaxLength = 16] +BuiltInNullableDataTypes.TestNullableDouble ---> [nullable varbinary] [MaxLength = 8] +BuiltInNullableDataTypes.TestNullableInt16 ---> [nullable varbinary] [MaxLength = 2] +BuiltInNullableDataTypes.TestNullableInt32 ---> [nullable varbinary] [MaxLength = 4] +BuiltInNullableDataTypes.TestNullableInt64 ---> [nullable varbinary] [MaxLength = 8] +BuiltInNullableDataTypes.TestNullableSignedByte ---> [nullable varbinary] [MaxLength = 1] +BuiltInNullableDataTypes.TestNullableSingle ---> [nullable varbinary] [MaxLength = 4] +BuiltInNullableDataTypes.TestNullableTimeSpan ---> [nullable varbinary] [MaxLength = 8] +BuiltInNullableDataTypes.TestNullableUnsignedInt16 ---> [nullable varbinary] [MaxLength = 2] +BuiltInNullableDataTypes.TestNullableUnsignedInt32 ---> [nullable varbinary] [MaxLength = 4] +BuiltInNullableDataTypes.TestNullableUnsignedInt64 ---> [nullable varbinary] [MaxLength = 8] +BuiltInNullableDataTypes.TestString ---> [nullable varbinary] [MaxLength = -1] +BuiltInNullableDataTypesShadow.Enum16 ---> [nullable varbinary] [MaxLength = 2] +BuiltInNullableDataTypesShadow.Enum32 ---> [nullable varbinary] [MaxLength = 4] +BuiltInNullableDataTypesShadow.Enum64 ---> [nullable varbinary] [MaxLength = 8] +BuiltInNullableDataTypesShadow.Enum8 ---> [nullable varbinary] [MaxLength = 1] +BuiltInNullableDataTypesShadow.EnumS8 ---> [nullable varbinary] [MaxLength = 1] +BuiltInNullableDataTypesShadow.EnumU16 ---> [nullable varbinary] [MaxLength = 2] +BuiltInNullableDataTypesShadow.EnumU32 ---> [nullable varbinary] [MaxLength = 4] +BuiltInNullableDataTypesShadow.EnumU64 ---> [nullable varbinary] [MaxLength = 8] +BuiltInNullableDataTypesShadow.Id ---> [varbinary] [MaxLength = 4] +BuiltInNullableDataTypesShadow.PartitionId ---> [varbinary] [MaxLength = 4] +BuiltInNullableDataTypesShadow.TestByteArray ---> [nullable varbinary] [MaxLength = -1] +BuiltInNullableDataTypesShadow.TestNullableBoolean ---> [nullable varbinary] [MaxLength = 1] +BuiltInNullableDataTypesShadow.TestNullableByte ---> [nullable varbinary] [MaxLength = 1] +BuiltInNullableDataTypesShadow.TestNullableCharacter ---> [nullable varbinary] [MaxLength = 2] +BuiltInNullableDataTypesShadow.TestNullableDateTime ---> [nullable varbinary] [MaxLength = 8] +BuiltInNullableDataTypesShadow.TestNullableDateTimeOffset ---> [nullable varbinary] [MaxLength = 12] +BuiltInNullableDataTypesShadow.TestNullableDecimal ---> [nullable varbinary] [MaxLength = 16] +BuiltInNullableDataTypesShadow.TestNullableDouble ---> [nullable varbinary] [MaxLength = 8] +BuiltInNullableDataTypesShadow.TestNullableInt16 ---> [nullable varbinary] [MaxLength = 2] +BuiltInNullableDataTypesShadow.TestNullableInt32 ---> [nullable varbinary] [MaxLength = 4] +BuiltInNullableDataTypesShadow.TestNullableInt64 ---> [nullable varbinary] [MaxLength = 8] +BuiltInNullableDataTypesShadow.TestNullableSignedByte ---> [nullable varbinary] [MaxLength = 1] +BuiltInNullableDataTypesShadow.TestNullableSingle ---> [nullable varbinary] [MaxLength = 4] +BuiltInNullableDataTypesShadow.TestNullableTimeSpan ---> [nullable varbinary] [MaxLength = 8] +BuiltInNullableDataTypesShadow.TestNullableUnsignedInt16 ---> [nullable varbinary] [MaxLength = 2] +BuiltInNullableDataTypesShadow.TestNullableUnsignedInt32 ---> [nullable varbinary] [MaxLength = 4] +BuiltInNullableDataTypesShadow.TestNullableUnsignedInt64 ---> [nullable varbinary] [MaxLength = 8] +BuiltInNullableDataTypesShadow.TestString ---> [nullable varbinary] [MaxLength = -1] +DateTimeEnclosure.DateTimeOffset ---> [nullable varbinary] [MaxLength = 12] +DateTimeEnclosure.Id ---> [varbinary] [MaxLength = 4] +EmailTemplate.Id ---> [varbinary] [MaxLength = 16] +EmailTemplate.TemplateType ---> [varbinary] [MaxLength = 4] +MaxLengthDataTypes.ByteArray5 ---> [nullable varbinary] [MaxLength = 5] +MaxLengthDataTypes.ByteArray9000 ---> [nullable varbinary] [MaxLength = -1] +MaxLengthDataTypes.Id ---> [varbinary] [MaxLength = 4] +MaxLengthDataTypes.String3 ---> [nullable varbinary] [MaxLength = 3] +MaxLengthDataTypes.String9000 ---> [nullable varbinary] [MaxLength = -1] +StringEnclosure.Id ---> [varbinary] [MaxLength = 4] +StringEnclosure.Value ---> [nullable varbinary] [MaxLength = -1] +StringForeignKeyDataType.Id ---> [varbinary] [MaxLength = 4] +StringForeignKeyDataType.StringKeyDataTypeId ---> [nullable varbinary] [MaxLength = 255] +StringKeyDataType.Id ---> [varbinary] [MaxLength = 255] +UnicodeDataTypes.Id ---> [varbinary] [MaxLength = 4] +UnicodeDataTypes.StringAnsi ---> [nullable varbinary] [MaxLength = -1] +UnicodeDataTypes.StringAnsi3 ---> [nullable varbinary] [MaxLength = 3] +UnicodeDataTypes.StringAnsi9000 ---> [nullable varbinary] [MaxLength = -1] +UnicodeDataTypes.StringDefault ---> [nullable varbinary] [MaxLength = -1] +UnicodeDataTypes.StringUnicode ---> [nullable varbinary] [MaxLength = -1] "; Assert.Equal(expected, actual, ignoreLineEndingDifferences: true); @@ -171,7 +172,7 @@ UnicodeDataTypes.StringUnicode ---> `nullable varbinary` [MaxLength = -1] public override void Can_read_back_mapped_enum_from_collection_first_or_default() { - // The query needs to generate TOP 1 + // The query needs to generate TOP(1) } public override void Can_read_back_bool_mapped_as_int_through_navigation() @@ -179,6 +180,21 @@ UnicodeDataTypes.StringUnicode ---> `nullable varbinary` [MaxLength = -1] // Column is mapped as int rather than byte[] } + public override void Object_to_string_conversion() + { + // Return values are string which byte[] cannot read + } + + public override void Can_compare_enum_to_constant() + { + // Column is mapped as int rather than byte[] + } + + public override void Can_compare_enum_to_parameter() + { + // Column is mapped as int rather than byte[] + } + public class EverythingIsBytesJetFixture : BuiltInDataTypesFixtureBase { public override bool StrictEquality => true; @@ -217,6 +233,15 @@ UnicodeDataTypes.StringUnicode ---> `nullable varbinary` [MaxLength = -1] .AddOptions(builder) .ConfigureWarnings( c => c.Log(JetEventId.DecimalTypeDefaultWarning)); + + protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) + { + base.OnModelCreating(modelBuilder, context); + + modelBuilder.Ignore(); + modelBuilder.Ignore(); + modelBuilder.Ignore(); + } } public class JetBytesTestStoreFactory : JetTestStoreFactory