Improve support for primitive collections and Json Types (#159)

pull/162/head
Christopher Jolly 2 years ago committed by GitHub
parent d32eae0867
commit fcb97a4e63
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -6,6 +6,7 @@ using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.Extensions.DependencyInjection;
namespace EntityFrameworkCore.Jet.Metadata.Internal
@ -100,6 +101,7 @@ namespace EntityFrameworkCore.Jet.Metadata.Internal
}
else
{
if (column is JsonColumn) yield break;
property = column.PropertyMappings.First().Property;
if (property.DeclaringType is IEntityType entityType)
{

@ -371,6 +371,17 @@ namespace EntityFrameworkCore.Jet.Query.Sql.Internal
return base.VisitColumn(columnExpression);
}
protected override Expression VisitJsonScalar(JsonScalarExpression jsonScalarExpression)
{
var path = jsonScalarExpression.Path;
if (path.Count == 0)
{
Visit(jsonScalarExpression.Json);
return jsonScalarExpression;
}
return base.VisitJsonScalar(jsonScalarExpression);
}
private bool IsNonComposedSetOperation(SelectExpression selectExpression)
=> selectExpression.Offset == null
&& selectExpression.Limit == null

@ -7,6 +7,7 @@ using System.Text;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Storage.Json;
namespace EntityFrameworkCore.Jet.Storage.Internal
{
@ -29,7 +30,7 @@ namespace EntityFrameworkCore.Jet.Storage.Internal
StoreTypePostfix? storeTypePostfix = null)
: base(
new RelationalTypeMappingParameters(
new CoreTypeMappingParameters(typeof(byte[]), null, comparer),
new CoreTypeMappingParameters(typeof(byte[]), null, comparer, jsonValueReaderWriter: JsonByteArrayReaderWriter.Instance),
storeType ?? (fixedLength ? "binary" : "varbinary"),
storeTypePostfix ?? StoreTypePostfix.Size,
System.Data.DbType.Binary,

@ -12,7 +12,7 @@ using Microsoft.EntityFrameworkCore.Storage;
namespace EntityFrameworkCore.Jet.Storage.Internal
{
public class JetDateTimeTypeMapping : RelationalTypeMapping
public class JetDateTimeTypeMapping : DateTimeTypeMapping
{
private const int MaxDateTimeDoublePrecision = 10;
private static readonly JetDecimalTypeMapping _decimalTypeMapping = new JetDecimalTypeMapping("decimal", System.Data.DbType.Decimal, 18, 10);
@ -23,7 +23,7 @@ namespace EntityFrameworkCore.Jet.Storage.Internal
[NotNull] IJetOptions options,
DbType? dbType = null,
[CanBeNull] Type? clrType = null)
: base(storeType, clrType ?? typeof(DateTime), dbType ?? System.Data.DbType.DateTime)
: base(storeType)
{
_options = options;
}
@ -40,13 +40,13 @@ namespace EntityFrameworkCore.Jet.Storage.Internal
protected override void ConfigureParameter(DbParameter parameter)
{
base.ConfigureParameter(parameter);
if (_options.EnableMillisecondsSupport &&
parameter.Value is DateTime dateTime)
{
parameter.Value = GetDateTimeDoubleValueAsDecimal(dateTime, _options.EnableMillisecondsSupport);
parameter.ResetDbType();
// Necessary to explicitly set for OLE DB, to apply the System.Decimal value as DOUBLE to Jet.
parameter.DbType = System.Data.DbType.Double;
}
@ -75,7 +75,7 @@ namespace EntityFrameworkCore.Jet.Storage.Internal
: "#");
literal.AppendFormat(CultureInfo.InvariantCulture, "{0:yyyy-MM-dd}", dateTime);
var time = dateTime.TimeOfDay;
if (time != TimeSpan.Zero)
{
@ -94,7 +94,7 @@ namespace EntityFrameworkCore.Jet.Storage.Internal
var millisecondsTicks = time.Ticks % TimeSpan.TicksPerSecond / TimeSpan.TicksPerMillisecond * TimeSpan.TicksPerMillisecond;
if (millisecondsTicks > 0)
{
var jetTimeDoubleFractions = Math.Round((decimal) millisecondsTicks / TimeSpan.TicksPerDay, MaxDateTimeDoublePrecision);
var jetTimeDoubleFractions = Math.Round((decimal)millisecondsTicks / TimeSpan.TicksPerDay, MaxDateTimeDoublePrecision);
literal
.Insert(0, "(")
@ -108,28 +108,28 @@ namespace EntityFrameworkCore.Jet.Storage.Internal
}
protected virtual DateTime ConvertToDateTimeCompatibleValue(object value)
=> (DateTime) value;
=> (DateTime)value;
private static decimal GetDateTimeDoubleValueAsDecimal(DateTime dateTime, bool millisecondsSupportEnabled)
{
//
// We are explicitly using System.Decimal here, so we get better scale results:
//
var checkDateTimeValue = CheckDateTimeValue(dateTime) - JetConfiguration.TimeSpanOffset;
if (millisecondsSupportEnabled)
{
// Round to milliseconds.
var millisecondsTicks = checkDateTimeValue.Ticks / TimeSpan.TicksPerMillisecond * TimeSpan.TicksPerMillisecond;
var result = /*Math.Round(*/(decimal) millisecondsTicks / TimeSpan.TicksPerDay/*, MaxDateTimeDoublePrecision, MidpointRounding.AwayFromZero)*/;
var result = /*Math.Round(*/(decimal)millisecondsTicks / TimeSpan.TicksPerDay/*, MaxDateTimeDoublePrecision, MidpointRounding.AwayFromZero)*/;
return result;
}
else
{
// Round to seconds.
var secondsTicks = checkDateTimeValue.Ticks / TimeSpan.TicksPerSecond * TimeSpan.TicksPerSecond;
var result = /*Math.Round(*/(decimal) secondsTicks / TimeSpan.TicksPerDay/*, MaxDateTimeDoublePrecision, MidpointRounding.AwayFromZero)*/;
var result = /*Math.Round(*/(decimal)secondsTicks / TimeSpan.TicksPerDay/*, MaxDateTimeDoublePrecision, MidpointRounding.AwayFromZero)*/;
return result;
}
}

@ -3,6 +3,7 @@ using System.Data.Common;
using System.Linq;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Storage.Json;
namespace EntityFrameworkCore.Jet.Storage.Internal
{
@ -28,7 +29,7 @@ namespace EntityFrameworkCore.Jet.Storage.Internal
StoreTypePostfix storeTypePostfix = StoreTypePostfix.PrecisionAndScale)
: base(
new RelationalTypeMappingParameters(
new CoreTypeMappingParameters(typeof(decimal)),
new CoreTypeMappingParameters(typeof(decimal), jsonValueReaderWriter: JsonDecimalReaderWriter.Instance),
storeType,
storeTypePostfix,
dbType)

@ -0,0 +1,113 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Data.Common;
using System.IO;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Text.Json;
using Microsoft.EntityFrameworkCore.Storage;
namespace EntityFrameworkCore.Jet.Storage.Internal;
/// <summary>
/// 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.
/// </summary>
public class JetJsonTypeMapping : JsonTypeMapping
{
private static readonly MethodInfo GetStringMethod
= typeof(DbDataReader).GetRuntimeMethod(nameof(DbDataReader.GetString), new[] { typeof(int) })!;
private static readonly PropertyInfo UTF8Property
= typeof(Encoding).GetProperty(nameof(Encoding.UTF8))!;
private static readonly MethodInfo EncodingGetBytesMethod
= typeof(Encoding).GetMethod(nameof(Encoding.GetBytes), new[] { typeof(string) })!;
private static readonly ConstructorInfo MemoryStreamConstructor
= typeof(MemoryStream).GetConstructor(new[] { typeof(byte[]) })!;
/// <summary>
/// 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.
/// </summary>
public static JetJsonTypeMapping Default { get; } = new("longchar");
/// <summary>
/// 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.
/// </summary>
public JetJsonTypeMapping(string storeType)
: base(storeType, typeof(JsonElement), System.Data.DbType.String)
{
}
/// <summary>
/// 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.
/// </summary>
public override MethodInfo GetDataReaderMethod()
=> GetStringMethod;
/// <summary>
/// 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.
/// </summary>
public override Expression CustomizeDataReaderExpression(Expression expression)
=> Expression.New(
MemoryStreamConstructor,
Expression.Call(
Expression.Property(null, UTF8Property),
EncodingGetBytesMethod,
expression));
/// <summary>
/// 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.
/// </summary>
protected JetJsonTypeMapping(RelationalTypeMappingParameters parameters)
: base(parameters)
{
}
/// <summary>
/// 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.
/// </summary>
protected virtual string EscapeSqlLiteral(string literal)
=> literal.Replace("'", "''");
/// <summary>
/// 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.
/// </summary>
protected override string GenerateNonNullSqlLiteral(object value)
=> $"'{EscapeSqlLiteral(JsonSerializer.Serialize(value))}'";
/// <summary>
/// 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.
/// </summary>
protected override RelationalTypeMapping Clone(RelationalTypeMappingParameters parameters)
=> new JetJsonTypeMapping(parameters);
}

@ -5,6 +5,7 @@ using System.Data;
using System.Data.Common;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Storage.Json;
namespace EntityFrameworkCore.Jet.Storage.Internal
{
@ -30,12 +31,12 @@ namespace EntityFrameworkCore.Jet.Storage.Internal
bool keepLineBreakCharacters = false)
: this(
new RelationalTypeMappingParameters(
new CoreTypeMappingParameters(typeof(string)),
new CoreTypeMappingParameters(typeof(string), jsonValueReaderWriter: JsonStringReaderWriter.Instance),
storeType ?? GetStoreName(fixedLength),
storeTypePostfix ?? StoreTypePostfix.Size,
(fixedLength
? System.Data.DbType.StringFixedLength
: (DbType?) System.Data.DbType.String),
: (DbType?)System.Data.DbType.String),
unicode,
size,
fixedLength),
@ -103,7 +104,7 @@ namespace EntityFrameworkCore.Jet.Storage.Internal
protected override string GenerateNonNullSqlLiteral(object value)
{
var escaped = $"'{EscapeSqlLiteral((string)value)}'";
// BUG: EF Core indents idempotent scripts, which can lead to unexpected values for strings
// that contain line breaks.
// Tracked by: https://github.com/aspnet/EntityFrameworkCore/issues/15256

@ -5,11 +5,13 @@ using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text.Json;
using EntityFrameworkCore.Jet.Infrastructure.Internal;
using EntityFrameworkCore.Jet.Internal;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Metadata.Conventions;
using Microsoft.EntityFrameworkCore.Storage;
namespace EntityFrameworkCore.Jet.Storage.Internal
@ -53,7 +55,7 @@ namespace EntityFrameworkCore.Jet.Storage.Internal
private readonly JetStringTypeMapping _variableLengthUnicodeString = new JetStringTypeMapping("varchar", unicode: true);
private readonly JetStringTypeMapping _variableLengthMaxUnicodeString = new JetStringTypeMapping("varchar(max)", unicode: true, storeTypePostfix: StoreTypePostfix.None);
private readonly JetStringTypeMapping _unboundedUnicodeString = new JetStringTypeMapping("longchar", unicode: true, storeTypePostfix: StoreTypePostfix.None);
private readonly JetJsonTypeMapping _jsonTypeMapping = new JetJsonTypeMapping("longchar");
private readonly JetGuidTypeMapping _guid = new JetGuidTypeMapping("uniqueidentifier", DbType.Guid);
private readonly JetByteArrayTypeMapping _rowversion = new JetByteArrayTypeMapping("varbinary", size: 8,
comparer: new ValueComparer<byte[]>(
@ -202,6 +204,7 @@ namespace EntityFrameworkCore.Jet.Storage.Internal
{typeof(TimeSpan), _timespan},
{typeof(TimeOnly), _timeonly},
{typeof(Guid), _guid},
{ typeof(JsonElement), _jsonTypeMapping }
};
// These are disallowed only if specified without any kind of length specified in parenthesis.
@ -261,7 +264,8 @@ namespace EntityFrameworkCore.Jet.Storage.Internal
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
protected override RelationalTypeMapping? FindMapping(in RelationalTypeMappingInfo mappingInfo)
=> base.FindMapping(mappingInfo) ?? FindRawMapping(mappingInfo)?.Clone(mappingInfo);
=> base.FindMapping(mappingInfo)
?? FindRawMapping(mappingInfo)?.WithTypeMappingInfo(mappingInfo);
/// <summary>
/// This API supports the Entity Framework Core infrastructure and is not intended to be used
@ -355,23 +359,26 @@ namespace EntityFrameworkCore.Jet.Storage.Internal
return _rowversion;
}
var isFixedLength = mappingInfo.IsFixedLength == true;
const int maxBinaryColumnSize = 510;
var size = mappingInfo.Size ?? (mappingInfo.IsKeyOrIndex ? (int?)maxBinaryColumnSize : null);
if (size > maxBinaryColumnSize)
if (mappingInfo.ElementTypeMapping == null)
{
size = isFixedLength ? maxBinaryColumnSize : (int?)null;
var isFixedLength = mappingInfo.IsFixedLength == true;
const int maxBinaryColumnSize = 510;
var size = mappingInfo.Size ?? (mappingInfo.IsKeyOrIndex ? (int?)maxBinaryColumnSize : null);
if (size > maxBinaryColumnSize)
{
size = isFixedLength ? maxBinaryColumnSize : (int?)null;
}
return size == null
? _unboundedBinary
: new JetByteArrayTypeMapping(
size: size,
storeType: isFixedLength
? _fixedLengthBinary.StoreTypeNameBase
: _variableLengthBinary.StoreTypeNameBase);
}
return size == null
? _unboundedBinary
: new JetByteArrayTypeMapping(
size: size,
storeType: isFixedLength
? _fixedLengthBinary.StoreTypeNameBase
: _variableLengthBinary.StoreTypeNameBase);
}
}

@ -4,6 +4,7 @@
#nullable enable
using System;
using System.Collections.Generic;
using EntityFrameworkCore.Jet.FunctionalTests.TestUtilities;
using Microsoft.EntityFrameworkCore;
using Xunit;
@ -13,20 +14,54 @@ namespace EntityFrameworkCore.Jet.FunctionalTests;
public class JsonTypesJetTest : JsonTypesRelationalTestBase
{
// #25765 - the Jet type mapping source doesn't support primitive collections, so we end up with a Property
// that has no ElementType; that causes the assertion on the element nullability to fail.
public override void Can_read_write_collection_of_string_JSON_values()
=> Assert.Throws<EqualException>(() => base.Can_read_write_collection_of_string_JSON_values());
// #25765 - the Jet type mapping source doesn't support primitive collections, so we end up with a Property
// that has no ElementType; that causes the assertion on the element nullability to fail.
public override void Can_read_write_collection_of_binary_JSON_values()
=> Assert.Throws<EqualException>(() => base.Can_read_write_collection_of_binary_JSON_values());
// #25765 - the Jet type mapping source doesn't support primitive collections, so we end up with a Property
// that has no ElementType; that causes the assertion on the element nullability to fail.
public override void Can_read_write_collection_of_nullable_string_JSON_values()
=> Assert.Throws<EqualException>(() => base.Can_read_write_collection_of_nullable_string_JSON_values());
public override void Can_read_write_ulong_enum_JSON_values(EnumU64 value, string json)
{
if (value == EnumU64.Max)
{
json = """{"Prop":-1}"""; // Because ulong is converted to long on Jet
}
base.Can_read_write_ulong_enum_JSON_values(value, json);
}
public override void Can_read_write_nullable_ulong_enum_JSON_values(object? value, string json)
{
if (Equals(value, ulong.MaxValue))
{
json = """{"Prop":-1}"""; // Because ulong is converted to long on Jet
}
base.Can_read_write_nullable_ulong_enum_JSON_values(value, json);
}
public override void Can_read_write_collection_of_ulong_enum_JSON_values()
=> Can_read_and_write_JSON_value<EnumU64CollectionType, List<EnumU64>>(
nameof(EnumU64CollectionType.EnumU64),
new List<EnumU64>
{
EnumU64.Min,
EnumU64.Max,
EnumU64.Default,
EnumU64.One,
(EnumU64)8
},
"""{"Prop":[0,-1,0,1,8]}""", // Because ulong is converted to long on Jet
mappedCollection: true);
public override void Can_read_write_collection_of_nullable_ulong_enum_JSON_values()
=> Can_read_and_write_JSON_value<NullableEnumU64CollectionType, List<EnumU64?>>(
nameof(NullableEnumU64CollectionType.EnumU64),
new List<EnumU64?>
{
EnumU64.Min,
null,
EnumU64.Max,
EnumU64.Default,
EnumU64.One,
(EnumU64?)8
},
"""{"Prop":[0,null,-1,0,1,8]}""", // Because ulong is converted to long on Jet
mappedCollection: true);
public override void Can_read_write_point()
// No built-in JSON support for spatial types in the Jet provider

@ -43,7 +43,7 @@ public class JsonQueryAdHocJetTest : JsonQueryAdHocTestBase
ctx.SaveChanges();
ctx.Database.ExecuteSqlRaw(@"INSERT INTO [Entities] ([Id], [Reference], [Collection])
VALUES(3, N'{{ ""NonNullableScalar"" : 30 }}', N'[{{ ""NonNullableScalar"" : 10001 }}]')");
VALUES(3, '{{ ""NonNullableScalar"" : 30 }}', '[{{ ""NonNullableScalar"" : 10001 }}]')");
}
protected override void Seed30028(MyContext30028 ctx)
@ -52,25 +52,25 @@ VALUES(3, N'{{ ""NonNullableScalar"" : 30 }}', N'[{{ ""NonNullableScalar"" : 100
ctx.Database.ExecuteSqlRaw(@"INSERT INTO [Entities] ([Id], [Json])
VALUES(
1,
N'{{""RootName"":""e1"",""Collection"":[{{""BranchName"":""e1 c1"",""Nested"":{{""LeafName"":""e1 c1 l""}}}},{{""BranchName"":""e1 c2"",""Nested"":{{""LeafName"":""e1 c2 l""}}}}],""OptionalReference"":{{""BranchName"":""e1 or"",""Nested"":{{""LeafName"":""e1 or l""}}}},""RequiredReference"":{{""BranchName"":""e1 rr"",""Nested"":{{""LeafName"":""e1 rr l""}}}}}}')");
'{{""RootName"":""e1"",""Collection"":[{{""BranchName"":""e1 c1"",""Nested"":{{""LeafName"":""e1 c1 l""}}}},{{""BranchName"":""e1 c2"",""Nested"":{{""LeafName"":""e1 c2 l""}}}}],""OptionalReference"":{{""BranchName"":""e1 or"",""Nested"":{{""LeafName"":""e1 or l""}}}},""RequiredReference"":{{""BranchName"":""e1 rr"",""Nested"":{{""LeafName"":""e1 rr l""}}}}}}')");
// missing collection
ctx.Database.ExecuteSqlRaw(@"INSERT INTO [Entities] ([Id], [Json])
VALUES(
2,
N'{{""RootName"":""e2"",""OptionalReference"":{{""BranchName"":""e2 or"",""Nested"":{{""LeafName"":""e2 or l""}}}},""RequiredReference"":{{""BranchName"":""e2 rr"",""Nested"":{{""LeafName"":""e2 rr l""}}}}}}')");
'{{""RootName"":""e2"",""OptionalReference"":{{""BranchName"":""e2 or"",""Nested"":{{""LeafName"":""e2 or l""}}}},""RequiredReference"":{{""BranchName"":""e2 rr"",""Nested"":{{""LeafName"":""e2 rr l""}}}}}}')");
// missing optional reference
ctx.Database.ExecuteSqlRaw(@"INSERT INTO [Entities] ([Id], [Json])
VALUES(
3,
N'{{""RootName"":""e3"",""Collection"":[{{""BranchName"":""e3 c1"",""Nested"":{{""LeafName"":""e3 c1 l""}}}},{{""BranchName"":""e3 c2"",""Nested"":{{""LeafName"":""e3 c2 l""}}}}],""RequiredReference"":{{""BranchName"":""e3 rr"",""Nested"":{{""LeafName"":""e3 rr l""}}}}}}')");
'{{""RootName"":""e3"",""Collection"":[{{""BranchName"":""e3 c1"",""Nested"":{{""LeafName"":""e3 c1 l""}}}},{{""BranchName"":""e3 c2"",""Nested"":{{""LeafName"":""e3 c2 l""}}}}],""RequiredReference"":{{""BranchName"":""e3 rr"",""Nested"":{{""LeafName"":""e3 rr l""}}}}}}')");
// missing required reference
ctx.Database.ExecuteSqlRaw(@"INSERT INTO [Entities] ([Id], [Json])
VALUES(
4,
N'{{""RootName"":""e4"",""Collection"":[{{""BranchName"":""e4 c1"",""Nested"":{{""LeafName"":""e4 c1 l""}}}},{{""BranchName"":""e4 c2"",""Nested"":{{""LeafName"":""e4 c2 l""}}}}],""OptionalReference"":{{""BranchName"":""e4 or"",""Nested"":{{""LeafName"":""e4 or l""}}}}}}')");
'{{""RootName"":""e4"",""Collection"":[{{""BranchName"":""e4 c1"",""Nested"":{{""LeafName"":""e4 c1 l""}}}},{{""BranchName"":""e4 c2"",""Nested"":{{""LeafName"":""e4 c2 l""}}}}],""OptionalReference"":{{""BranchName"":""e4 or"",""Nested"":{{""LeafName"":""e4 or l""}}}}}}')");
}
protected override void SeedArrayOfPrimitives(MyContextArrayOfPrimitives ctx)
@ -129,10 +129,10 @@ N'{{""RootName"":""e4"",""Collection"":[{{""BranchName"":""e4 c1"",""Nested"":{{
{
ctx.Database.ExecuteSqlRaw(@"INSERT INTO [Entities] ([Collection], [CollectionWithCtor], [Reference], [ReferenceWithCtor], [Id])
VALUES(
N'[{{""JunkReference"":{{""Something"":""SomeValue"" }},""Name"":""c11"",""JunkProperty1"":50,""Number"":11.5,""JunkCollection1"":[],""JunkCollection2"":[{{""Foo"":""junk value""}}],""NestedCollection"":[{{""DoB"":""2002-04-01T00:00:00"",""DummyProp"":""Dummy value""}},{{""DoB"":""2002-04-02T00:00:00"",""DummyReference"":{{""Foo"":5}}}}],""NestedReference"":{{""DoB"":""2002-03-01T00:00:00""}}}},{{""Name"":""c12"",""Number"":12.5,""NestedCollection"":[{{""DoB"":""2002-06-01T00:00:00""}},{{""DoB"":""2002-06-02T00:00:00""}}],""NestedDummy"":59,""NestedReference"":{{""DoB"":""2002-05-01T00:00:00""}}}}]',
N'[{{""MyBool"":true,""Name"":""c11 ctor"",""JunkReference"":{{""Something"":""SomeValue"",""JunkCollection"":[{{""Foo"":""junk value""}}]}},""NestedCollection"":[{{""DoB"":""2002-08-01T00:00:00""}},{{""DoB"":""2002-08-02T00:00:00""}}],""NestedReference"":{{""DoB"":""2002-07-01T00:00:00""}}}},{{""MyBool"":false,""Name"":""c12 ctor"",""NestedCollection"":[{{""DoB"":""2002-10-01T00:00:00""}},{{""DoB"":""2002-10-02T00:00:00""}}],""JunkCollection"":[{{""Foo"":""junk value""}}],""NestedReference"":{{""DoB"":""2002-09-01T00:00:00""}}}}]',
N'{{""Name"":""r1"",""JunkCollection"":[{{""Foo"":""junk value""}}],""JunkReference"":{{""Something"":""SomeValue"" }},""Number"":1.5,""NestedCollection"":[{{""DoB"":""2000-02-01T00:00:00"",""JunkReference"":{{""Something"":""SomeValue""}}}},{{""DoB"":""2000-02-02T00:00:00""}}],""NestedReference"":{{""DoB"":""2000-01-01T00:00:00""}}}}',
N'{{""MyBool"":true,""JunkCollection"":[{{""Foo"":""junk value""}}],""Name"":""r1 ctor"",""JunkReference"":{{""Something"":""SomeValue"" }},""NestedCollection"":[{{""DoB"":""2001-02-01T00:00:00""}},{{""DoB"":""2001-02-02T00:00:00""}}],""NestedReference"":{{""JunkCollection"":[{{""Foo"":""junk value""}}],""DoB"":""2001-01-01T00:00:00""}}}}',
'[{{""JunkReference"":{{""Something"":""SomeValue"" }},""Name"":""c11"",""JunkProperty1"":50,""Number"":11.5,""JunkCollection1"":[],""JunkCollection2"":[{{""Foo"":""junk value""}}],""NestedCollection"":[{{""DoB"":""2002-04-01T00:00:00"",""DummyProp"":""Dummy value""}},{{""DoB"":""2002-04-02T00:00:00"",""DummyReference"":{{""Foo"":5}}}}],""NestedReference"":{{""DoB"":""2002-03-01T00:00:00""}}}},{{""Name"":""c12"",""Number"":12.5,""NestedCollection"":[{{""DoB"":""2002-06-01T00:00:00""}},{{""DoB"":""2002-06-02T00:00:00""}}],""NestedDummy"":59,""NestedReference"":{{""DoB"":""2002-05-01T00:00:00""}}}}]',
'[{{""MyBool"":true,""Name"":""c11 ctor"",""JunkReference"":{{""Something"":""SomeValue"",""JunkCollection"":[{{""Foo"":""junk value""}}]}},""NestedCollection"":[{{""DoB"":""2002-08-01T00:00:00""}},{{""DoB"":""2002-08-02T00:00:00""}}],""NestedReference"":{{""DoB"":""2002-07-01T00:00:00""}}}},{{""MyBool"":false,""Name"":""c12 ctor"",""NestedCollection"":[{{""DoB"":""2002-10-01T00:00:00""}},{{""DoB"":""2002-10-02T00:00:00""}}],""JunkCollection"":[{{""Foo"":""junk value""}}],""NestedReference"":{{""DoB"":""2002-09-01T00:00:00""}}}}]',
'{{""Name"":""r1"",""JunkCollection"":[{{""Foo"":""junk value""}}],""JunkReference"":{{""Something"":""SomeValue"" }},""Number"":1.5,""NestedCollection"":[{{""DoB"":""2000-02-01T00:00:00"",""JunkReference"":{{""Something"":""SomeValue""}}}},{{""DoB"":""2000-02-02T00:00:00""}}],""NestedReference"":{{""DoB"":""2000-01-01T00:00:00""}}}}',
'{{""MyBool"":true,""JunkCollection"":[{{""Foo"":""junk value""}}],""Name"":""r1 ctor"",""JunkReference"":{{""Something"":""SomeValue"" }},""NestedCollection"":[{{""DoB"":""2001-02-01T00:00:00""}},{{""DoB"":""2001-02-02T00:00:00""}}],""NestedReference"":{{""JunkCollection"":[{{""Foo"":""junk value""}}],""DoB"":""2001-01-01T00:00:00""}}}}',
1)");
}
@ -140,11 +140,11 @@ N'{{""MyBool"":true,""JunkCollection"":[{{""Foo"":""junk value""}}],""Name"":""r
{
ctx.Database.ExecuteSqlRaw(@"INSERT INTO [Entities] ([Collection], [CollectionWithCtor], [Reference], [ReferenceWithCtor], [Id], [Name])
VALUES(
N'[{{""Name"":""e1_c1"",""ShadowDouble"":5.5}},{{""ShadowDouble"":20.5,""Name"":""e1_c2""}}]',
N'[{{""Name"":""e1_c1 ctor"",""ShadowNullableByte"":6}},{{""ShadowNullableByte"":null,""Name"":""e1_c2 ctor""}}]',
N'{{""Name"":""e1_r"", ""ShadowString"":""Foo""}}',
N'{{""ShadowInt"":143,""Name"":""e1_r ctor""}}',
'[{{""Name"":""e1_c1"",""ShadowDouble"":5.5}},{{""ShadowDouble"":20.5,""Name"":""e1_c2""}}]',
'[{{""Name"":""e1_c1 ctor"",""ShadowNullableByte"":6}},{{""ShadowNullableByte"":null,""Name"":""e1_c2 ctor""}}]',
'{{""Name"":""e1_r"", ""ShadowString"":""Foo""}}',
'{{""ShadowInt"":143,""Name"":""e1_r ctor""}}',
1,
N'e1')");
'e1')");
}
}

@ -18,7 +18,7 @@ namespace EntityFrameworkCore.Jet.FunctionalTests.Query;
/// This exercises the older translation paths for e.g. Contains, to make sure things work for providers with no queryable constant/
/// parameter support.
/// </summary>
public class PrimitiveCollectionsQueryJetTest : PrimitiveCollectionsQueryTestBase<
public class PrimitiveCollectionsQueryJetTest : PrimitiveCollectionsQueryRelationalTestBase<
PrimitiveCollectionsQueryJetTest.PrimitiveCollectionsQueryJetFixture>
{
public PrimitiveCollectionsQueryJetTest(PrimitiveCollectionsQueryJetFixture fixture, ITestOutputHelper testOutputHelper)
@ -33,10 +33,10 @@ public class PrimitiveCollectionsQueryJetTest : PrimitiveCollectionsQueryTestBas
await base.Inline_collection_of_ints_Contains(async);
AssertSql(
"""
SELECT [p].[Id], [p].[Bool], [p].[Bools], [p].[DateTime], [p].[DateTimes], [p].[Enum], [p].[Enums], [p].[Int], [p].[Ints], [p].[NullableInt], [p].[NullableInts], [p].[NullableString], [p].[NullableStrings], [p].[String], [p].[Strings]
FROM [PrimitiveCollectionsEntity] AS [p]
WHERE [p].[Int] IN (10, 999)
"""
SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings`
FROM `PrimitiveCollectionsEntity` AS `p`
WHERE `p`.`Int` IN (10, 999)
""");
}
@ -45,10 +45,10 @@ WHERE [p].[Int] IN (10, 999)
await base.Inline_collection_of_nullable_ints_Contains(async);
AssertSql(
"""
SELECT [p].[Id], [p].[Bool], [p].[Bools], [p].[DateTime], [p].[DateTimes], [p].[Enum], [p].[Enums], [p].[Int], [p].[Ints], [p].[NullableInt], [p].[NullableInts], [p].[NullableString], [p].[NullableStrings], [p].[String], [p].[Strings]
FROM [PrimitiveCollectionsEntity] AS [p]
WHERE [p].[NullableInt] IN (10, 999)
"""
SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings`
FROM `PrimitiveCollectionsEntity` AS `p`
WHERE `p`.`NullableInt` IN (10, 999)
""");
}
@ -57,10 +57,10 @@ WHERE [p].[NullableInt] IN (10, 999)
await base.Inline_collection_of_nullable_ints_Contains_null(async);
AssertSql(
"""
SELECT [p].[Id], [p].[Bool], [p].[Bools], [p].[DateTime], [p].[DateTimes], [p].[Enum], [p].[Enums], [p].[Int], [p].[Ints], [p].[NullableInt], [p].[NullableInts], [p].[NullableString], [p].[NullableStrings], [p].[String], [p].[Strings]
FROM [PrimitiveCollectionsEntity] AS [p]
WHERE [p].[NullableInt] IS NULL OR [p].[NullableInt] = 999
"""
SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings`
FROM `PrimitiveCollectionsEntity` AS `p`
WHERE `p`.`NullableInt` IS NULL OR `p`.`NullableInt` = 999
""");
}
@ -124,10 +124,10 @@ WHERE (
await base.Inline_collection_Contains_with_one_value(async);
AssertSql(
"""
SELECT [p].[Id], [p].[Bool], [p].[Bools], [p].[DateTime], [p].[DateTimes], [p].[Enum], [p].[Enums], [p].[Int], [p].[Ints], [p].[NullableInt], [p].[NullableInts], [p].[NullableString], [p].[NullableStrings], [p].[String], [p].[Strings]
FROM [PrimitiveCollectionsEntity] AS [p]
WHERE [p].[Id] = 2
"""
SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings`
FROM `PrimitiveCollectionsEntity` AS `p`
WHERE `p`.`Id` = 2
""");
}
@ -136,10 +136,10 @@ WHERE [p].[Id] = 2
await base.Inline_collection_Contains_with_two_values(async);
AssertSql(
"""
SELECT [p].[Id], [p].[Bool], [p].[Bools], [p].[DateTime], [p].[DateTimes], [p].[Enum], [p].[Enums], [p].[Int], [p].[Ints], [p].[NullableInt], [p].[NullableInts], [p].[NullableString], [p].[NullableStrings], [p].[String], [p].[Strings]
FROM [PrimitiveCollectionsEntity] AS [p]
WHERE [p].[Id] IN (2, 999)
"""
SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings`
FROM `PrimitiveCollectionsEntity` AS `p`
WHERE `p`.`Id` IN (2, 999)
""");
}
@ -148,10 +148,10 @@ WHERE [p].[Id] IN (2, 999)
await base.Inline_collection_Contains_with_three_values(async);
AssertSql(
"""
SELECT [p].[Id], [p].[Bool], [p].[Bools], [p].[DateTime], [p].[DateTimes], [p].[Enum], [p].[Enums], [p].[Int], [p].[Ints], [p].[NullableInt], [p].[NullableInts], [p].[NullableString], [p].[NullableStrings], [p].[String], [p].[Strings]
FROM [PrimitiveCollectionsEntity] AS [p]
WHERE [p].[Id] IN (2, 999, 1000)
"""
SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings`
FROM `PrimitiveCollectionsEntity` AS `p`
WHERE `p`.`Id` IN (2, 999, 1000)
""");
}
@ -160,13 +160,13 @@ WHERE [p].[Id] IN (2, 999, 1000)
await base.Inline_collection_Contains_with_all_parameters(async);
AssertSql(
"""
"""
@__i_0='2'
@__j_1='999'
SELECT [p].[Id], [p].[Bool], [p].[Bools], [p].[DateTime], [p].[DateTimes], [p].[Enum], [p].[Enums], [p].[Int], [p].[Ints], [p].[NullableInt], [p].[NullableInts], [p].[NullableString], [p].[NullableStrings], [p].[String], [p].[Strings]
FROM [PrimitiveCollectionsEntity] AS [p]
WHERE [p].[Id] IN (@__i_0, @__j_1)
SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings`
FROM `PrimitiveCollectionsEntity` AS `p`
WHERE `p`.`Id` IN (@__i_0, @__j_1)
""");
}
@ -175,12 +175,12 @@ WHERE [p].[Id] IN (@__i_0, @__j_1)
await base.Inline_collection_Contains_with_constant_and_parameter(async);
AssertSql(
"""
"""
@__j_0='999'
SELECT [p].[Id], [p].[Bool], [p].[Bools], [p].[DateTime], [p].[DateTimes], [p].[Enum], [p].[Enums], [p].[Int], [p].[Ints], [p].[NullableInt], [p].[NullableInts], [p].[NullableString], [p].[NullableStrings], [p].[String], [p].[Strings]
FROM [PrimitiveCollectionsEntity] AS [p]
WHERE [p].[Id] IN (2, @__j_0)
SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings`
FROM `PrimitiveCollectionsEntity` AS `p`
WHERE `p`.`Id` IN (2, @__j_0)
""");
}
@ -189,12 +189,12 @@ WHERE [p].[Id] IN (2, @__j_0)
await base.Inline_collection_Contains_with_mixed_value_types(async);
AssertSql(
"""
"""
@__i_0='11'
SELECT [p].[Id], [p].[Bool], [p].[Bools], [p].[DateTime], [p].[DateTimes], [p].[Enum], [p].[Enums], [p].[Int], [p].[Ints], [p].[NullableInt], [p].[NullableInts], [p].[NullableString], [p].[NullableStrings], [p].[String], [p].[Strings]
FROM [PrimitiveCollectionsEntity] AS [p]
WHERE [p].[Int] IN (999, @__i_0, [p].[Id], [p].[Id] + [p].[Int])
SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings`
FROM `PrimitiveCollectionsEntity` AS `p`
WHERE `p`.`Int` IN (999, @__i_0, `p`.`Id`, `p`.`Id` + `p`.`Int`)
""");
}
@ -203,10 +203,10 @@ WHERE [p].[Int] IN (999, @__i_0, [p].[Id], [p].[Id] + [p].[Int])
await base.Inline_collection_Contains_as_Any_with_predicate(async);
AssertSql(
"""
SELECT [p].[Id], [p].[Bool], [p].[Bools], [p].[DateTime], [p].[DateTimes], [p].[Enum], [p].[Enums], [p].[Int], [p].[Ints], [p].[NullableInt], [p].[NullableInts], [p].[NullableString], [p].[NullableStrings], [p].[String], [p].[Strings]
FROM [PrimitiveCollectionsEntity] AS [p]
WHERE [p].[Id] IN (2, 999)
"""
SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings`
FROM `PrimitiveCollectionsEntity` AS `p`
WHERE `p`.`Id` IN (2, 999)
""");
}
@ -215,10 +215,10 @@ WHERE [p].[Id] IN (2, 999)
await base.Inline_collection_negated_Contains_as_All(async);
AssertSql(
"""
SELECT [p].[Id], [p].[Bool], [p].[Bools], [p].[DateTime], [p].[DateTimes], [p].[Enum], [p].[Enums], [p].[Int], [p].[Ints], [p].[NullableInt], [p].[NullableInts], [p].[NullableString], [p].[NullableStrings], [p].[String], [p].[Strings]
FROM [PrimitiveCollectionsEntity] AS [p]
WHERE [p].[Id] NOT IN (2, 999)
"""
SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings`
FROM `PrimitiveCollectionsEntity` AS `p`
WHERE `p`.`Id` NOT IN (2, 999)
""");
}
@ -232,10 +232,10 @@ WHERE [p].[Id] NOT IN (2, 999)
await base.Parameter_collection_of_ints_Contains(async);
AssertSql(
"""
SELECT [p].[Id], [p].[Bool], [p].[Bools], [p].[DateTime], [p].[DateTimes], [p].[Enum], [p].[Enums], [p].[Int], [p].[Ints], [p].[NullableInt], [p].[NullableInts], [p].[NullableString], [p].[NullableStrings], [p].[String], [p].[Strings]
FROM [PrimitiveCollectionsEntity] AS [p]
WHERE [p].[Int] IN (10, 999)
"""
SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings`
FROM `PrimitiveCollectionsEntity` AS `p`
WHERE `p`.`Int` IN (10, 999)
""");
}
@ -244,10 +244,10 @@ WHERE [p].[Int] IN (10, 999)
await base.Parameter_collection_of_nullable_ints_Contains_int(async);
AssertSql(
"""
SELECT [p].[Id], [p].[Bool], [p].[Bools], [p].[DateTime], [p].[DateTimes], [p].[Enum], [p].[Enums], [p].[Int], [p].[Ints], [p].[NullableInt], [p].[NullableInts], [p].[NullableString], [p].[NullableStrings], [p].[String], [p].[Strings]
FROM [PrimitiveCollectionsEntity] AS [p]
WHERE [p].[Int] IN (10, 999)
"""
SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings`
FROM `PrimitiveCollectionsEntity` AS `p`
WHERE `p`.`Int` IN (10, 999)
""");
}
@ -256,10 +256,10 @@ WHERE [p].[Int] IN (10, 999)
await base.Parameter_collection_of_nullable_ints_Contains_nullable_int(async);
AssertSql(
"""
SELECT [p].[Id], [p].[Bool], [p].[Bools], [p].[DateTime], [p].[DateTimes], [p].[Enum], [p].[Enums], [p].[Int], [p].[Ints], [p].[NullableInt], [p].[NullableInts], [p].[NullableString], [p].[NullableStrings], [p].[String], [p].[Strings]
FROM [PrimitiveCollectionsEntity] AS [p]
WHERE [p].[NullableInt] IS NULL OR [p].[NullableInt] = 999
"""
SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings`
FROM `PrimitiveCollectionsEntity` AS `p`
WHERE `p`.`NullableInt` IS NULL OR `p`.`NullableInt` = 999
""");
}
@ -268,10 +268,10 @@ WHERE [p].[NullableInt] IS NULL OR [p].[NullableInt] = 999
await base.Parameter_collection_of_strings_Contains_non_nullable_string(async);
AssertSql(
"""
SELECT [p].[Id], [p].[Bool], [p].[Bools], [p].[DateTime], [p].[DateTimes], [p].[Enum], [p].[Enums], [p].[Int], [p].[Ints], [p].[NullableInt], [p].[NullableInts], [p].[NullableString], [p].[NullableStrings], [p].[String], [p].[Strings]
FROM [PrimitiveCollectionsEntity] AS [p]
WHERE [p].[String] IN (N'10', N'999')
"""
SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings`
FROM `PrimitiveCollectionsEntity` AS `p`
WHERE `p`.`String` IN ('10', '999')
""");
}
@ -280,10 +280,10 @@ WHERE [p].[String] IN (N'10', N'999')
await base.Parameter_collection_of_strings_Contains_nullable_string(async);
AssertSql(
"""
SELECT [p].[Id], [p].[Bool], [p].[Bools], [p].[DateTime], [p].[DateTimes], [p].[Enum], [p].[Enums], [p].[Int], [p].[Ints], [p].[NullableInt], [p].[NullableInts], [p].[NullableString], [p].[NullableStrings], [p].[String], [p].[Strings]
FROM [PrimitiveCollectionsEntity] AS [p]
WHERE [p].[NullableString] IS NULL OR [p].[NullableString] = N'999'
"""
SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings`
FROM `PrimitiveCollectionsEntity` AS `p`
WHERE `p`.`NullableString` IS NULL OR `p`.`NullableString` = '999'
""");
}
@ -292,10 +292,10 @@ WHERE [p].[NullableString] IS NULL OR [p].[NullableString] = N'999'
await base.Parameter_collection_of_DateTimes_Contains(async);
AssertSql(
"""
SELECT [p].[Id], [p].[Bool], [p].[Bools], [p].[DateTime], [p].[DateTimes], [p].[Enum], [p].[Enums], [p].[Int], [p].[Ints], [p].[NullableInt], [p].[NullableInts], [p].[NullableString], [p].[NullableStrings], [p].[String], [p].[Strings]
FROM [PrimitiveCollectionsEntity] AS [p]
WHERE [p].[DateTime] IN ('2020-01-10T12:30:00.0000000Z', '9999-01-01T00:00:00.0000000Z')
"""
SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings`
FROM `PrimitiveCollectionsEntity` AS `p`
WHERE `p`.`DateTime` IN (#2020-01-10 12:30:00#, #9999-01-01#)
""");
}
@ -304,10 +304,10 @@ WHERE [p].[DateTime] IN ('2020-01-10T12:30:00.0000000Z', '9999-01-01T00:00:00.00
await base.Parameter_collection_of_bools_Contains(async);
AssertSql(
"""
SELECT [p].[Id], [p].[Bool], [p].[Bools], [p].[DateTime], [p].[DateTimes], [p].[Enum], [p].[Enums], [p].[Int], [p].[Ints], [p].[NullableInt], [p].[NullableInts], [p].[NullableString], [p].[NullableStrings], [p].[String], [p].[Strings]
FROM [PrimitiveCollectionsEntity] AS [p]
WHERE [p].[Bool] = CAST(1 AS bit)
"""
SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings`
FROM `PrimitiveCollectionsEntity` AS `p`
WHERE `p`.`Bool` = TRUE
""");
}
@ -316,10 +316,10 @@ WHERE [p].[Bool] = CAST(1 AS bit)
await base.Parameter_collection_of_enums_Contains(async);
AssertSql(
"""
SELECT [p].[Id], [p].[Bool], [p].[Bools], [p].[DateTime], [p].[DateTimes], [p].[Enum], [p].[Enums], [p].[Int], [p].[Ints], [p].[NullableInt], [p].[NullableInts], [p].[NullableString], [p].[NullableStrings], [p].[String], [p].[Strings]
FROM [PrimitiveCollectionsEntity] AS [p]
WHERE [p].[Enum] IN (0, 3)
"""
SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings`
FROM `PrimitiveCollectionsEntity` AS `p`
WHERE `p`.`Enum` IN (0, 3)
""");
}
@ -328,9 +328,9 @@ WHERE [p].[Enum] IN (0, 3)
await base.Parameter_collection_null_Contains(async);
AssertSql(
"""
SELECT [p].[Id], [p].[Bool], [p].[Bools], [p].[DateTime], [p].[DateTimes], [p].[Enum], [p].[Enums], [p].[Int], [p].[Ints], [p].[NullableInt], [p].[NullableInts], [p].[NullableString], [p].[NullableStrings], [p].[String], [p].[Strings]
FROM [PrimitiveCollectionsEntity] AS [p]
"""
SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings`
FROM `PrimitiveCollectionsEntity` AS `p`
WHERE 0 = 1
""");
}
@ -479,10 +479,10 @@ WHERE (
await base.Column_collection_projection_from_top_level(async);
AssertSql(
"""
SELECT [p].[Ints]
FROM [PrimitiveCollectionsEntity] AS [p]
ORDER BY [p].[Id]
"""
SELECT `p`.`Ints`
FROM `PrimitiveCollectionsEntity` AS `p`
ORDER BY `p`.`Id`
""");
}
@ -519,12 +519,12 @@ ORDER BY [p].[Id]
await base.Column_collection_equality_parameter_collection(async);
AssertSql(
"""
@__ints_0='[1,10]' (Size = 4000)
"""
@__ints_0='[1,10]' (Size = 255)
SELECT [p].[Id], [p].[Bool], [p].[Bools], [p].[DateTime], [p].[DateTimes], [p].[Enum], [p].[Enums], [p].[Int], [p].[Ints], [p].[NullableInt], [p].[NullableInts], [p].[NullableString], [p].[NullableStrings], [p].[String], [p].[Strings]
FROM [PrimitiveCollectionsEntity] AS [p]
WHERE [p].[Ints] = @__ints_0
SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings`
FROM `PrimitiveCollectionsEntity` AS `p`
WHERE `p`.`Ints` = @__ints_0
""");
}
@ -533,10 +533,10 @@ WHERE [p].[Ints] = @__ints_0
await base.Column_collection_equality_inline_collection(async);
AssertSql(
"""
SELECT [p].[Id], [p].[Bool], [p].[Bools], [p].[DateTime], [p].[DateTimes], [p].[Enum], [p].[Enums], [p].[Int], [p].[Ints], [p].[NullableInt], [p].[NullableInts], [p].[NullableString], [p].[NullableStrings], [p].[String], [p].[Strings]
FROM [PrimitiveCollectionsEntity] AS [p]
WHERE [p].[Ints] = N'[1,10]'
"""
SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings`
FROM `PrimitiveCollectionsEntity` AS `p`
WHERE `p`.`Ints` = '[1,10]'
""");
}
@ -586,10 +586,10 @@ WHERE [p].[Ints] = N'[1,10]'
await base.Project_collection_of_ints_simple(async);
AssertSql(
"""
SELECT [p].[Ints]
FROM [PrimitiveCollectionsEntity] AS [p]
ORDER BY [p].[Id]
"""
SELECT `p`.`Ints`
FROM `PrimitiveCollectionsEntity` AS `p`
ORDER BY `p`.`Id`
""");
}
@ -608,10 +608,10 @@ ORDER BY [p].[Id]
// client eval
AssertSql(
"""
SELECT [p].[Ints]
FROM [PrimitiveCollectionsEntity] AS [p]
ORDER BY [p].[Id]
"""
SELECT `p`.`Ints`
FROM `PrimitiveCollectionsEntity` AS `p`
ORDER BY `p`.`Id`
""");
}
@ -635,11 +635,11 @@ ORDER BY [p].[Id]
await base.Project_primitive_collections_element(async);
AssertSql(
"""
SELECT [p].[Ints], [p].[DateTimes], [p].[Strings]
FROM [PrimitiveCollectionsEntity] AS [p]
WHERE [p].[Id] < 4
ORDER BY [p].[Id]
"""
SELECT `p`.`Ints`, `p`.`DateTimes`, `p`.`Strings`
FROM `PrimitiveCollectionsEntity` AS `p`
WHERE `p`.`Id` < 4
ORDER BY `p`.`Id`
""");
}

Loading…
Cancel
Save