Initial support for DateOnly/TimeOnly

pull/144/head
Christopher Jolly 2 years ago
parent ba913012ce
commit c1d263aedc

@ -176,7 +176,16 @@ namespace EntityFrameworkCore.Jet.Data
return (DateTime)value;
}
return (DateTime)value;
public DateOnly GetDateOnly(int ordinal)
{
var value = GetDateTime(ordinal);
return DateOnly.FromDateTime(value);
}
public TimeOnly GetTimeOnly(int ordinal)
{
var value = GetDateTime(ordinal);
return TimeOnly.FromDateTime(value);
}
public virtual TimeSpan GetTimeSpan(int ordinal)
@ -472,6 +481,14 @@ namespace EntityFrameworkCore.Jet.Data
{
return (T)(object)GetDateTime(ordinal);
}
if (typeof(T) == typeof(DateOnly))
{
return (T)(object)GetDateOnly(ordinal);
}
if (typeof(T) == typeof(TimeOnly))
{
return (T)(object)GetTimeOnly(ordinal);
}
if (typeof(T) == typeof(TimeSpan))
{
return (T)(object)GetTimeSpan(ordinal);

@ -0,0 +1,63 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Collections.Generic;
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;
/// <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 JetDateOnlyMemberTranslator : IMemberTranslator
{
private static readonly Dictionary<string, string> DatePartMapping
= new()
{
{ nameof(DateTime.Year), "yyyy" },
{ nameof(DateTime.Month), "m" },
{ nameof(DateTime.DayOfYear), "y" },
{ nameof(DateTime.Day), "d" }
};
private readonly ISqlExpressionFactory _sqlExpressionFactory;
/// <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 JetDateOnlyMemberTranslator(ISqlExpressionFactory sqlExpressionFactory)
{
_sqlExpressionFactory = sqlExpressionFactory;
}
/// <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 virtual SqlExpression? Translate(
SqlExpression? instance,
MemberInfo member,
Type returnType,
IDiagnosticsLogger<DbLoggerCategory.Query> logger)
=> member.DeclaringType == typeof(DateOnly) && DatePartMapping.TryGetValue(member.Name, out var datePart)
? _sqlExpressionFactory.Function(
"DATEPART",
new[] { _sqlExpressionFactory.Constant(datePart), instance! },
nullable: true,
argumentsPropagateNullability: new[] { false, true },
returnType)
: null;
}

@ -0,0 +1,77 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Collections.Generic;
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;
/// <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 JetDateOnlyMethodTranslator : IMethodCallTranslator
{
private readonly Dictionary<MethodInfo, string> _methodInfoDatePartMapping = new()
{
{ typeof(DateOnly).GetRuntimeMethod(nameof(DateOnly.AddYears), new[] { typeof(int) })!, "yyyy" },
{ typeof(DateOnly).GetRuntimeMethod(nameof(DateOnly.AddMonths), new[] { typeof(int) })!, "m" },
{ typeof(DateOnly).GetRuntimeMethod(nameof(DateOnly.AddDays), new[] { typeof(int) })!, "d" }
};
private readonly ISqlExpressionFactory _sqlExpressionFactory;
/// <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 JetDateOnlyMethodTranslator(ISqlExpressionFactory sqlExpressionFactory)
{
_sqlExpressionFactory = sqlExpressionFactory;
}
/// <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 virtual SqlExpression? Translate(
SqlExpression? instance,
MethodInfo method,
IReadOnlyList<SqlExpression> arguments,
IDiagnosticsLogger<DbLoggerCategory.Query> logger)
{
if (_methodInfoDatePartMapping.TryGetValue(method, out var datePart)
&& instance != null)
{
instance = _sqlExpressionFactory.ApplyDefaultTypeMapping(instance);
return _sqlExpressionFactory.Function(
"DATEADD",
new[] { _sqlExpressionFactory.Constant(datePart), _sqlExpressionFactory.Convert(arguments[0], typeof(int)), instance },
nullable: true,
argumentsPropagateNullability: new[] { false, true, true },
instance.Type,
instance.TypeMapping);
}
if (method.DeclaringType == typeof(DateOnly)
&& method.Name == nameof(DateOnly.FromDateTime)
&& arguments.Count == 1)
{
return _sqlExpressionFactory.Convert(arguments[0], typeof(DateOnly));
}
return null;
}
}

@ -23,9 +23,11 @@ namespace EntityFrameworkCore.Jet.Query.ExpressionTranslators.Internal
// ReSharper disable once VirtualMemberCallInConstructor
AddTranslators(new IMemberTranslator[]
{
new JetStringMemberTranslator(sqlExpressionFactory),
new JetDateOnlyMemberTranslator(sqlExpressionFactory),
new JetDateTimeMemberTranslator(sqlExpressionFactory),
new JetTimeSpanMemberTranslator(sqlExpressionFactory)
new JetStringMemberTranslator(sqlExpressionFactory),
new JetTimeSpanMemberTranslator(sqlExpressionFactory),
new JetTimeOnlyMemberTranslator(sqlExpressionFactory)
});
}
}

@ -28,6 +28,7 @@ namespace EntityFrameworkCore.Jet.Query.ExpressionTranslators.Internal
new JetByteArrayMethodTranslator(sqlExpressionFactory),
new JetConvertTranslator(sqlExpressionFactory),
new JetDateDiffFunctionsTranslator(sqlExpressionFactory),
new JetDateOnlyMethodTranslator(sqlExpressionFactory),
new JetDateTimeMethodTranslator(sqlExpressionFactory),
new JetIsDateFunctionTranslator(sqlExpressionFactory),
new JetMathTranslator(sqlExpressionFactory),
@ -35,6 +36,7 @@ namespace EntityFrameworkCore.Jet.Query.ExpressionTranslators.Internal
new JetObjectToStringTranslator(sqlExpressionFactory),
new JetStringMethodTranslator(sqlExpressionFactory),
new JetRandomTranslator(sqlExpressionFactory),
new JetTimeOnlyMethodTranslator(sqlExpressionFactory)
});
}
}

@ -0,0 +1,66 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Collections.Generic;
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;
/// <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 JetTimeOnlyMemberTranslator : IMemberTranslator
{
private static readonly Dictionary<string, string> DatePartMappings = new()
{
{ nameof(TimeOnly.Hour), "h" },
{ nameof(TimeOnly.Minute), "n" },
{ nameof(TimeOnly.Second), "s" },
{ nameof(TimeOnly.Millisecond), "millisecond" }
};
private readonly ISqlExpressionFactory _sqlExpressionFactory;
/// <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 JetTimeOnlyMemberTranslator(ISqlExpressionFactory sqlExpressionFactory)
{
_sqlExpressionFactory = sqlExpressionFactory;
}
/// <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 virtual SqlExpression? Translate(
SqlExpression? instance,
MemberInfo member,
Type returnType,
IDiagnosticsLogger<DbLoggerCategory.Query> logger)
{
if (member.DeclaringType == typeof(TimeOnly) && DatePartMappings.TryGetValue(member.Name, out var value))
{
return _sqlExpressionFactory.Function(
"DATEPART", new[] { _sqlExpressionFactory.Constant(value), instance! },
nullable: true,
argumentsPropagateNullability: new[] { false, true },
returnType);
}
return null;
}
}

@ -0,0 +1,103 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Collections.Generic;
using System.Reflection;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.EntityFrameworkCore.Query.SqlExpressions;
using ExpressionExtensions = Microsoft.EntityFrameworkCore.Query.ExpressionExtensions;
namespace EntityFrameworkCore.Jet.Query.ExpressionTranslators.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 JetTimeOnlyMethodTranslator : IMethodCallTranslator
{
private static readonly MethodInfo AddHoursMethod = typeof(TimeOnly).GetRuntimeMethod(
nameof(TimeOnly.AddHours), new[] { typeof(double) })!;
private static readonly MethodInfo AddMinutesMethod = typeof(TimeOnly).GetRuntimeMethod(
nameof(TimeOnly.AddMinutes), new[] { typeof(double) })!;
private static readonly MethodInfo IsBetweenMethod = typeof(TimeOnly).GetRuntimeMethod(
nameof(TimeOnly.IsBetween), new[] { typeof(TimeOnly), typeof(TimeOnly) })!;
private readonly ISqlExpressionFactory _sqlExpressionFactory;
/// <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 JetTimeOnlyMethodTranslator(ISqlExpressionFactory sqlExpressionFactory)
{
_sqlExpressionFactory = sqlExpressionFactory;
}
/// <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 virtual SqlExpression? Translate(
SqlExpression? instance,
MethodInfo method,
IReadOnlyList<SqlExpression> arguments,
IDiagnosticsLogger<DbLoggerCategory.Query> logger)
{
if (method.DeclaringType != typeof(TimeOnly) || instance is null)
{
return null;
}
if (method == AddHoursMethod || method == AddMinutesMethod)
{
var datePart = method == AddHoursMethod ? "h" : "n";
// Some Add methods accept a double, and SQL Server DateAdd does not accept number argument outside of int range
if (arguments[0] is SqlConstantExpression { Value: double and (<= int.MinValue or >= int.MaxValue) })
{
return null;
}
instance = _sqlExpressionFactory.ApplyDefaultTypeMapping(instance);
var dadd = _sqlExpressionFactory.Function(
"DATEADD",
new[] { _sqlExpressionFactory.Constant(datePart), _sqlExpressionFactory.Convert(arguments[0], typeof(int)), instance },
nullable: true,
argumentsPropagateNullability: new[] { false, true, true },
instance.Type,
instance.TypeMapping);
return _sqlExpressionFactory.Function("TIMEVALUE", new[] { dadd }, true,
argumentsPropagateNullability: new[] { true }, instance.Type, instance.TypeMapping);
}
// Translate TimeOnly.IsBetween to a >= b AND a < c.
// Since a is evaluated multiple times, only translate for simple constructs (i.e. avoid duplicating complex subqueries).
if (method == IsBetweenMethod
&& instance is ColumnExpression or SqlConstantExpression or SqlParameterExpression)
{
var typeMapping = ExpressionExtensions.InferTypeMapping(instance, arguments[0], arguments[1]);
instance = _sqlExpressionFactory.ApplyTypeMapping(instance, typeMapping);
return _sqlExpressionFactory.And(
_sqlExpressionFactory.GreaterThanOrEqual(
instance,
_sqlExpressionFactory.ApplyTypeMapping(arguments[0], typeMapping)),
_sqlExpressionFactory.LessThan(
instance,
_sqlExpressionFactory.ApplyTypeMapping(arguments[1], typeMapping)));
}
return null;
}
}

@ -0,0 +1,94 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Data;
using System.Data.Common;
using System.Globalization;
using System.Reflection.Metadata;
using System.Text;
using EntityFrameworkCore.Jet.Data;
using EntityFrameworkCore.Jet.Infrastructure.Internal;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Storage;
namespace EntityFrameworkCore.Jet.Storage.Internal
{
public class JetDateOnlyTypeMapping : DateOnlyTypeMapping
{
private readonly IJetOptions _options;
public JetDateOnlyTypeMapping(
[NotNull] string storeType,
[NotNull] IJetOptions options,
DbType? dbType = null)
: base(storeType, dbType ?? System.Data.DbType.DateTime)
{
_options = options;
}
protected JetDateOnlyTypeMapping(RelationalTypeMappingParameters parameters, IJetOptions options)
: base(parameters)
{
_options = options;
}
protected override RelationalTypeMapping Clone(RelationalTypeMappingParameters parameters)
=> new JetDateOnlyTypeMapping(parameters, _options);
protected override void ConfigureParameter(DbParameter parameter)
{
base.ConfigureParameter(parameter);
if (parameter.Value != null)
{
((DateOnly)parameter.Value).Deconstruct(out int year, out int month, out int day);
parameter.Value = new DateTime(year, month, day);
}
}
protected override string GenerateNonNullSqlLiteral(object value)
=> GenerateNonNullSqlLiteral(value, false);
public virtual string GenerateNonNullSqlLiteral(object value, bool defaultClauseCompatible)
{
var dateTime = ConvertToDateTimeCompatibleValue(value);
dateTime = CheckDateTimeValue(dateTime);
var literal = new StringBuilder();
literal.Append(
defaultClauseCompatible
? "'"
: "#");
literal.AppendFormat(CultureInfo.InvariantCulture, "{0:yyyy-MM-dd}", dateTime);
literal.Append(
defaultClauseCompatible
? "'"
: "#");
return literal.ToString();
}
protected virtual DateTime ConvertToDateTimeCompatibleValue(object value)
{
((DateOnly)value).Deconstruct(out int year, out int month, out int day);
return new DateTime(year, month, day);
}
private static DateTime CheckDateTimeValue(DateTime dateTime)
{
if (dateTime < JetConfiguration.TimeSpanOffset)
{
if (dateTime != default)
{
throw new InvalidOperationException($"The {nameof(DateTime)} value '{dateTime}' is smaller than the minimum supported value of '{JetConfiguration.TimeSpanOffset}'.");
}
dateTime = JetConfiguration.TimeSpanOffset;
}
return dateTime;
}
}
}

@ -0,0 +1,58 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Data;
using System.Data.Common;
using EntityFrameworkCore.Jet.Data;
using EntityFrameworkCore.Jet.Infrastructure.Internal;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Storage;
namespace EntityFrameworkCore.Jet.Storage.Internal
{
public class JetTimeOnlyTypeMapping : TimeOnlyTypeMapping
{
[NotNull] private readonly IJetOptions _options;
public JetTimeOnlyTypeMapping(
[NotNull] string storeType,
[NotNull] IJetOptions options)
: base(storeType, System.Data.DbType.DateTime)
{
_options = options;
}
protected JetTimeOnlyTypeMapping(RelationalTypeMappingParameters parameters, IJetOptions options)
: base(parameters)
{
_options = options;
}
protected override void ConfigureParameter(DbParameter parameter)
{
base.ConfigureParameter(parameter);
if (parameter.Value != null)
{
((TimeOnly)parameter.Value).Deconstruct(out int hour, out int min, out int sec);
parameter.Value = JetConfiguration.TimeSpanOffset.Add(new TimeSpan(hour, min, sec));
}
}
protected override RelationalTypeMapping Clone(RelationalTypeMappingParameters parameters)
=> new JetTimeOnlyTypeMapping(parameters, _options);
protected override string GenerateNonNullSqlLiteral(object value)
{
//Format time without any milliseconds
if (!_options.EnableMillisecondsSupport)
{
return FormattableString.Invariant($@"TIMEVALUE('{value:HH\:mm\:ss}')");
}
else
{
//TODO: Treat as double
return "";
}
}
}
}

@ -45,8 +45,9 @@ namespace EntityFrameworkCore.Jet.Storage.Internal
private readonly JetDateTimeTypeMapping _datetime;
private readonly JetDateTimeOffsetTypeMapping _datetimeoffset;
private readonly JetDateTimeTypeMapping _date;
private readonly JetTimeSpanTypeMapping _time;
private readonly JetDateOnlyTypeMapping _dateonly;
private readonly JetTimeSpanTypeMapping _timespan;
private readonly JetTimeOnlyTypeMapping _timeonly;
private readonly JetStringTypeMapping _fixedLengthUnicodeString = new JetStringTypeMapping("char", unicode: true);
private readonly JetStringTypeMapping _variableLengthUnicodeString = new JetStringTypeMapping("varchar", unicode: true);
@ -87,8 +88,9 @@ namespace EntityFrameworkCore.Jet.Storage.Internal
_datetime = new JetDateTimeTypeMapping("datetime", options, dbType: DbType.DateTime);
_datetimeoffset = new JetDateTimeOffsetTypeMapping("datetime", options);
_date = new JetDateTimeTypeMapping("datetime", options, dbType: DbType.Date);
_time = new JetTimeSpanTypeMapping("datetime", options);
_dateonly = new JetDateOnlyTypeMapping("datetime", options, dbType: DbType.Date);
_timeonly = new JetTimeOnlyTypeMapping("datetime", options);
_timespan = new JetTimeSpanTypeMapping("datetime", options);
_storeTypeMappings
= new Dictionary<string, RelationalTypeMapping>(StringComparer.OrdinalIgnoreCase)
@ -147,8 +149,8 @@ namespace EntityFrameworkCore.Jet.Storage.Internal
{"money", _currency},
{"datetime", _datetime},
{"date", _date},
{"time", _time},
{"date", _dateonly},
{"time", _timeonly},
{"char", _fixedLengthUnicodeString},
{"alphanumeric", _fixedLengthUnicodeString},
@ -195,8 +197,10 @@ namespace EntityFrameworkCore.Jet.Storage.Internal
{typeof(double), _double},
{typeof(decimal), _decimal}, // CHECK: Is this supported or do we need to use CURRENCY?
{typeof(DateTime), _datetime},
{typeof(DateOnly), _dateonly},
{typeof(DateTimeOffset), _datetimeoffset},
{typeof(TimeSpan), _time},
{typeof(TimeSpan), _timespan},
{typeof(TimeOnly), _timeonly},
{typeof(Guid), _guid},
};

@ -22,22 +22,11 @@ namespace EntityFrameworkCore.Jet.FunctionalTests.Query
modelBuilder.Entity<City>().Property(g => g.Location).HasColumnType("varchar(100)");
/*modelBuilder.Entity<Mission>(
b =>
{
// Full-text binary search
b.Property<byte[]>("BriefingDocument");
b.Property<string>("BriefingDocumentFileExtension").HasColumnType("nvarchar(16)");
});*/
// No support yet for DateOnly/TimeOnly (#24507)
modelBuilder.Entity<Mission>(
b =>
{
b.Ignore(m => m.Date);
b.Ignore(m => m.Time);
//b.Ignore(m => m.Timeline);
//b.Ignore(m => m.Duration);
// b.Ignore(m => m.Duration);
});
}

@ -6346,12 +6346,8 @@ FROM `Missions` AS `m`
WHERE (({AssertSqlHelper.Parameter("@__start_0")} <= CAST(CONVERT(date, `m`.`Timeline`) AS datetimeoffset)) AND (`m`.`Timeline` < {AssertSqlHelper.Parameter("@__end_1")})) AND `m`.`Timeline` IN ('1902-01-02T10:00:00.1234567+01:30')");
}
public override async Task DateTimeOffsetNow_minus_timespan(bool async)
{
await base.DateTimeOffsetNow_minus_timespan(async);
AssertSql();
}
public override Task DateTimeOffsetNow_minus_timespan(bool async)
=> AssertTranslationFailed(() => base.DateTimeOffsetNow_minus_timespan(async));
public override async Task Navigation_inside_interpolated_string_expanded(bool isAsync)
{
@ -7477,7 +7473,7 @@ FROM `Missions` AS `m`
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Duration`, `m`.`Rating`, `m`.`Timeline`
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEPART('h', `m`.`Duration`) = 1
""");
@ -7489,7 +7485,7 @@ WHERE DATEPART('h', `m`.`Duration`) = 1
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Duration`, `m`.`Rating`, `m`.`Timeline`
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEPART('n', `m`.`Duration`) = 1
""");
@ -7501,7 +7497,7 @@ WHERE DATEPART('n', `m`.`Duration`) = 1
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Duration`, `m`.`Rating`, `m`.`Timeline`
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEPART('s', `m`.`Duration`) = 1
""");
@ -7997,19 +7993,27 @@ ORDER BY `g`.`Nickname`, `g`.`SquadId`, `c`.`Name`
await base.FirstOrDefault_on_empty_collection_of_DateTime_in_subquery(async);
AssertSql(
"""
SELECT `g`.`Nickname`, COALESCE((
SELECT TOP(1) `t1`.`IssueDate`
FROM `Tags` AS `t1`
WHERE `t1`.`GearNickName` = `g`.`FullName`
ORDER BY `t1`.`Id`), '0001-01-01T00:00:00.0000000') AS `invalidTagIssueDate`
"""
SELECT `g`.`Nickname`, IIF((
SELECT TOP 1 `t1`.`IssueDate`
FROM `Tags` AS `t1`
WHERE `t1`.`GearNickName` = `g`.`FullName`
ORDER BY `t1`.`Id`) IS NULL, #1899-12-30#, (
SELECT TOP 1 `t1`.`IssueDate`
FROM `Tags` AS `t1`
WHERE `t1`.`GearNickName` = `g`.`FullName`
ORDER BY `t1`.`Id`)) AS `invalidTagIssueDate`
FROM `Gears` AS `g`
LEFT JOIN `Tags` AS `t` ON `g`.`Nickname` = `t`.`GearNickName` AND `g`.`SquadId` = `t`.`GearSquadId`
WHERE `t`.`IssueDate` > COALESCE((
SELECT TOP(1) `t0`.`IssueDate`
FROM `Tags` AS `t0`
WHERE `t0`.`GearNickName` = `g`.`FullName`
ORDER BY `t0`.`Id`), '0001-01-01T00:00:00.0000000')
WHERE `t`.`IssueDate` > IIF((
SELECT TOP 1 `t0`.`IssueDate`
FROM `Tags` AS `t0`
WHERE `t0`.`GearNickName` = `g`.`FullName`
ORDER BY `t0`.`Id`) IS NULL, #1899-12-30#, (
SELECT TOP 1 `t0`.`IssueDate`
FROM `Tags` AS `t0`
WHERE `t0`.`GearNickName` = `g`.`FullName`
ORDER BY `t0`.`Id`))
""");
}
@ -8506,39 +8510,54 @@ ORDER BY `t`.`Id`, `t1`.`Nickname`, `t1`.`FullName`, `t1`.`HasSoulPatch`
public override async Task Where_DateOnly_Year(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_DateOnly_Year(async));
await base.Where_DateOnly_Year(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEPART('yyyy', `m`.`Date`) = 1990
""");
}
public override async Task Where_DateOnly_Month(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_DateOnly_Month(async));
await base.Where_DateOnly_Month(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEPART('m', `m`.`Date`) = 11
""");
}
public override async Task Where_DateOnly_Day(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_DateOnly_Day(async));
await base.Where_DateOnly_Day(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEPART('d', `m`.`Date`) = 10
""");
}
public override async Task Where_DateOnly_DayOfYear(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_DateOnly_DayOfYear(async));
await base.Where_DateOnly_DayOfYear(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEPART('y', `m`.`Date`) = 314
""");
}
public override async Task Where_DateOnly_DayOfWeek(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_DateOnly_DayOfWeek(async));
AssertSql();
@ -8546,79 +8565,114 @@ ORDER BY `t`.`Id`, `t1`.`Nickname`, `t1`.`FullName`, `t1`.`HasSoulPatch`
public override async Task Where_DateOnly_AddYears(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_DateOnly_AddYears(async));
await base.Where_DateOnly_AddYears(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEADD('yyyy', CLNG(3), `m`.`Date`) = #1993-11-10#
""");
}
public override async Task Where_DateOnly_AddMonths(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_DateOnly_AddMonths(async));
await base.Where_DateOnly_AddMonths(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEADD('m', CLNG(3), `m`.`Date`) = #1991-02-10#
""");
}
public override async Task Where_DateOnly_AddDays(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_DateOnly_AddDays(async));
await base.Where_DateOnly_AddDays(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEADD('d', CLNG(3), `m`.`Date`) = #1990-11-13#
""");
}
public override async Task Where_TimeOnly_Hour(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_TimeOnly_Hour(async));
await base.Where_TimeOnly_Hour(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEPART('h', `m`.`Time`) = 10
""");
}
public override async Task Where_TimeOnly_Minute(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_TimeOnly_Minute(async));
await base.Where_TimeOnly_Minute(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEPART('n', `m`.`Time`) = 15
""");
}
public override async Task Where_TimeOnly_Second(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_TimeOnly_Second(async));
await base.Where_TimeOnly_Second(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEPART('s', `m`.`Time`) = 50
""");
}
public override async Task Where_TimeOnly_Millisecond(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_TimeOnly_Millisecond(async));
await base.Where_TimeOnly_Millisecond(async);
AssertSql();
AssertSql(
"""
SELECT [m].[Id], [m].[BriefingDocument], [m].[BriefingDocumentFileExtension], [m].[CodeName], [m].[Date], [m].[Duration], [m].[Rating], [m].[Time], [m].[Timeline]
FROM [Missions] AS [m]
WHERE DATEPART(millisecond, [m].[Time]) = 500
""");
}
public override async Task Where_TimeOnly_AddHours(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_TimeOnly_AddHours(async));
await base.Where_TimeOnly_AddHours(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE TIMEVALUE(DATEADD('h', CLNG(3.0), `m`.`Time`)) = TIMEVALUE('13:15:50')
""");
}
public override async Task Where_TimeOnly_AddMinutes(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_TimeOnly_AddMinutes(async));
await base.Where_TimeOnly_AddMinutes(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE TIMEVALUE(DATEADD('n', CLNG(3.0), `m`.`Time`)) = TIMEVALUE('10:18:50')
""");
}
public override async Task Where_TimeOnly_Add_TimeSpan(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_TimeOnly_Add_TimeSpan(async));
AssertSql();
@ -8626,15 +8680,18 @@ ORDER BY `t`.`Id`, `t1`.`Nickname`, `t1`.`FullName`, `t1`.`HasSoulPatch`
public override async Task Where_TimeOnly_IsBetween(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_TimeOnly_IsBetween(async));
await base.Where_TimeOnly_IsBetween(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE (IIF(`m`.`Time` >= TIMEVALUE('10:00:00'), TRUE, FALSE) BAND IIF(`m`.`Time` < TIMEVALUE('11:00:00'), TRUE, FALSE)) = TRUE
""");
}
public override async Task Where_TimeOnly_subtract_TimeOnly(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_TimeOnly_subtract_TimeOnly(async));
AssertSql();
@ -8898,8 +8955,8 @@ ORDER BY `f`.`Id`
await base.Where_equals_method_on_nullable_with_object_overload(async);
AssertSql(
"""
SELECT `m`.`Id`, `m`.`BriefingDocument`, `m`.`BriefingDocumentFileExtension`, `m`.`CodeName`, `m`.`Duration`, `m`.`Rating`, `m`.`Timeline`
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE `m`.`Rating` IS NULL
""");

@ -2318,9 +2318,9 @@ WHERE 0 = 1");
AssertSql(
"""
SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate]
FROM [Orders] AS [o]
WHERE [o].[OrderDate] IS NOT NULL AND CAST([o].[OrderDate] AS date) = '1996-09-16'
SELECT `o`.`OrderID`, `o`.`CustomerID`, `o`.`EmployeeID`, `o`.`OrderDate`
FROM `Orders` AS `o`
WHERE `o`.`OrderDate` IS NOT NULL AND `o`.`OrderDate` = #1996-09-16#
""");
}

@ -27,8 +27,8 @@ public class TPCGearsOfWarQueryJetFixture : TPCGearsOfWarQueryRelationalFixture
modelBuilder.Entity<Mission>(
b =>
{
b.Ignore(m => m.Date);
b.Ignore(m => m.Time);
//b.Ignore(m => m.Date);
//b.Ignore(m => m.Time);
});
}

@ -10302,10 +10302,10 @@ FROM [Missions] AS [m]
await base.Where_TimeSpan_Hours(async);
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Duration`, `m`.`Rating`, `m`.`Timeline`
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEPART('s', `m`.`Duration`) = 1
WHERE DATEPART('h', `m`.`Duration`) = 1
""");
}
@ -10314,8 +10314,8 @@ WHERE DATEPART('s', `m`.`Duration`) = 1
await base.Where_TimeSpan_Minutes(async);
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Duration`, `m`.`Rating`, `m`.`Timeline`
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEPART('n', `m`.`Duration`) = 1
""");
@ -10326,8 +10326,8 @@ WHERE DATEPART('n', `m`.`Duration`) = 1
await base.Where_TimeSpan_Seconds(async);
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Duration`, `m`.`Rating`, `m`.`Timeline`
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEPART('s', `m`.`Duration`) = 1
""");
@ -11432,39 +11432,54 @@ ORDER BY IIF(`t`.`GearNickName` IS NOT NULL, `t0`.`SquadId`, NULL), `t`.`Note`
public override async Task Where_DateOnly_Year(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_DateOnly_Year(async));
await base.Where_DateOnly_Year(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEPART('yyyy', `m`.`Date`) = 1990
""");
}
public override async Task Where_DateOnly_Month(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_DateOnly_Month(async));
await base.Where_DateOnly_Month(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEPART('m', `m`.`Date`) = 11
""");
}
public override async Task Where_DateOnly_Day(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_DateOnly_Day(async));
await base.Where_DateOnly_Day(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEPART('d', `m`.`Date`) = 10
""");
}
public override async Task Where_DateOnly_DayOfYear(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_DateOnly_DayOfYear(async));
await base.Where_DateOnly_DayOfYear(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEPART('y', `m`.`Date`) = 314
""");
}
public override async Task Where_DateOnly_DayOfWeek(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_DateOnly_DayOfWeek(async));
AssertSql();
@ -11472,79 +11487,114 @@ ORDER BY IIF(`t`.`GearNickName` IS NOT NULL, `t0`.`SquadId`, NULL), `t`.`Note`
public override async Task Where_DateOnly_AddYears(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_DateOnly_AddYears(async));
await base.Where_DateOnly_AddYears(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEADD('yyyy', CLNG(3), `m`.`Date`) = #1993-11-10#
""");
}
public override async Task Where_DateOnly_AddMonths(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_DateOnly_AddMonths(async));
await base.Where_DateOnly_AddMonths(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEADD('m', CLNG(3), `m`.`Date`) = #1991-02-10#
""");
}
public override async Task Where_DateOnly_AddDays(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_DateOnly_AddDays(async));
await base.Where_DateOnly_AddDays(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEADD('d', CLNG(3), `m`.`Date`) = #1990-11-13#
""");
}
public override async Task Where_TimeOnly_Hour(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_TimeOnly_Hour(async));
await base.Where_TimeOnly_Hour(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEPART('h', `m`.`Time`) = 10
""");
}
public override async Task Where_TimeOnly_Minute(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_TimeOnly_Minute(async));
await base.Where_TimeOnly_Minute(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEPART('n', `m`.`Time`) = 15
""");
}
public override async Task Where_TimeOnly_Second(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_TimeOnly_Second(async));
await base.Where_TimeOnly_Second(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEPART('s', `m`.`Time`) = 50
""");
}
public override async Task Where_TimeOnly_Millisecond(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_TimeOnly_Millisecond(async));
await base.Where_TimeOnly_Millisecond(async);
AssertSql();
AssertSql(
"""
SELECT [m].[Id], [m].[CodeName], [m].[Date], [m].[Duration], [m].[Rating], [m].[Time], [m].[Timeline]
FROM [Missions] AS [m]
WHERE DATEPART(millisecond, [m].[Time]) = 500
""");
}
public override async Task Where_TimeOnly_AddHours(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_TimeOnly_AddHours(async));
await base.Where_TimeOnly_AddHours(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE TIMEVALUE(DATEADD('h', CLNG(3.0), `m`.`Time`)) = TIMEVALUE('13:15:50')
""");
}
public override async Task Where_TimeOnly_AddMinutes(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_TimeOnly_AddMinutes(async));
await base.Where_TimeOnly_AddMinutes(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE TIMEVALUE(DATEADD('n', CLNG(3.0), `m`.`Time`)) = TIMEVALUE('10:18:50')
""");
}
public override async Task Where_TimeOnly_Add_TimeSpan(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_TimeOnly_Add_TimeSpan(async));
AssertSql();
@ -11552,15 +11602,18 @@ ORDER BY IIF(`t`.`GearNickName` IS NOT NULL, `t0`.`SquadId`, NULL), `t`.`Note`
public override async Task Where_TimeOnly_IsBetween(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_TimeOnly_IsBetween(async));
await base.Where_TimeOnly_IsBetween(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE (IIF(`m`.`Time` >= TIMEVALUE('10:00:00'), TRUE, FALSE) BAND IIF(`m`.`Time` < TIMEVALUE('11:00:00'), TRUE, FALSE)) = TRUE
""");
}
public override async Task Where_TimeOnly_subtract_TimeOnly(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_TimeOnly_subtract_TimeOnly(async));
AssertSql();
@ -11938,25 +11991,33 @@ WHERE `l`.`ServerAddress` = '127.0.0.1'
await base.FirstOrDefault_on_empty_collection_of_DateTime_in_subquery(async);
AssertSql(
"""
SELECT [t].[Nickname], COALESCE((
SELECT TOP(1) [t2].[IssueDate]
FROM [Tags] AS [t2]
WHERE [t2].[GearNickName] = [t].[FullName]
ORDER BY [t2].[Id]), '0001-01-01T00:00:00.0000000') AS [invalidTagIssueDate]
"""
SELECT `t`.`Nickname`, IIF((
SELECT TOP 1 `t2`.`IssueDate`
FROM `Tags` AS `t2`
WHERE `t2`.`GearNickName` = `t`.`FullName`
ORDER BY `t2`.`Id`) IS NULL, #1899-12-30#, (
SELECT TOP 1 `t2`.`IssueDate`
FROM `Tags` AS `t2`
WHERE `t2`.`GearNickName` = `t`.`FullName`
ORDER BY `t2`.`Id`)) AS `invalidTagIssueDate`
FROM (
SELECT [g].[Nickname], [g].[SquadId], [g].[FullName]
FROM [Gears] AS [g]
SELECT `g`.`Nickname`, `g`.`SquadId`, `g`.`FullName`
FROM `Gears` AS `g`
UNION ALL
SELECT [o].[Nickname], [o].[SquadId], [o].[FullName]
FROM [Officers] AS [o]
) AS [t]
LEFT JOIN [Tags] AS [t0] ON [t].[Nickname] = [t0].[GearNickName] AND [t].[SquadId] = [t0].[GearSquadId]
WHERE [t0].[IssueDate] > COALESCE((
SELECT TOP(1) [t1].[IssueDate]
FROM [Tags] AS [t1]
WHERE [t1].[GearNickName] = [t].[FullName]
ORDER BY [t1].[Id]), '0001-01-01T00:00:00.0000000')
SELECT `o`.`Nickname`, `o`.`SquadId`, `o`.`FullName`
FROM `Officers` AS `o`
) AS `t`
LEFT JOIN `Tags` AS `t0` ON `t`.`Nickname` = `t0`.`GearNickName` AND `t`.`SquadId` = `t0`.`GearSquadId`
WHERE `t0`.`IssueDate` > IIF((
SELECT TOP 1 `t1`.`IssueDate`
FROM `Tags` AS `t1`
WHERE `t1`.`GearNickName` = `t`.`FullName`
ORDER BY `t1`.`Id`) IS NULL, #1899-12-30#, (
SELECT TOP 1 `t1`.`IssueDate`
FROM `Tags` AS `t1`
WHERE `t1`.`GearNickName` = `t`.`FullName`
ORDER BY `t1`.`Id`))
""");
}
@ -12101,10 +12162,10 @@ ORDER BY [t].[Nickname], [t].[SquadId]
await base.Where_equals_method_on_nullable_with_object_overload(async);
AssertSql(
"""
SELECT [m].[Id], [m].[CodeName], [m].[Duration], [m].[Rating], [m].[Timeline]
FROM [Missions] AS [m]
WHERE [m].[Rating] IS NULL
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE `m`.`Rating` IS NULL
""");
}

@ -24,8 +24,8 @@ public class TPTGearsOfWarQueryJetFixture : TPTGearsOfWarQueryRelationalFixture
modelBuilder.Entity<Mission>(
b =>
{
b.Ignore(m => m.Date);
b.Ignore(m => m.Time);
//b.Ignore(m => m.Date);
//b.Ignore(m => m.Time);
});
}

@ -8385,10 +8385,10 @@ FROM [Missions] AS [m]
await base.Where_TimeSpan_Hours(async);
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Duration`, `m`.`Rating`, `m`.`Timeline`
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEPART('n', `m`.`Duration`) = 1
WHERE DATEPART('h', `m`.`Duration`) = 1
""");
}
@ -8398,7 +8398,7 @@ WHERE DATEPART('n', `m`.`Duration`) = 1
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Duration`, `m`.`Rating`, `m`.`Timeline`
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEPART('n', `m`.`Duration`) = 1
""");
@ -8410,7 +8410,7 @@ WHERE DATEPART('n', `m`.`Duration`) = 1
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Duration`, `m`.`Rating`, `m`.`Timeline`
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEPART('s', `m`.`Duration`) = 1
""");
@ -9259,39 +9259,54 @@ ORDER BY IIF(`t`.`GearNickName` IS NOT NULL, `t0`.`SquadId`, NULL), `t`.`Note`
public override async Task Where_DateOnly_Year(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_DateOnly_Year(async));
await base.Where_DateOnly_Year(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEPART('yyyy', `m`.`Date`) = 1990
""");
}
public override async Task Where_DateOnly_Month(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_DateOnly_Month(async));
await base.Where_DateOnly_Month(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEPART('m', `m`.`Date`) = 11
""");
}
public override async Task Where_DateOnly_Day(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_DateOnly_Day(async));
await base.Where_DateOnly_Day(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEPART('d', `m`.`Date`) = 10
""");
}
public override async Task Where_DateOnly_DayOfYear(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_DateOnly_DayOfYear(async));
await base.Where_DateOnly_DayOfYear(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEPART('y', `m`.`Date`) = 314
""");
}
public override async Task Where_DateOnly_DayOfWeek(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_DateOnly_DayOfWeek(async));
AssertSql();
@ -9299,79 +9314,114 @@ ORDER BY IIF(`t`.`GearNickName` IS NOT NULL, `t0`.`SquadId`, NULL), `t`.`Note`
public override async Task Where_DateOnly_AddYears(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_DateOnly_AddYears(async));
await base.Where_DateOnly_AddYears(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEADD('yyyy', CLNG(3), `m`.`Date`) = #1993-11-10#
""");
}
public override async Task Where_DateOnly_AddMonths(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_DateOnly_AddMonths(async));
await base.Where_DateOnly_AddMonths(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEADD('m', CLNG(3), `m`.`Date`) = #1991-02-10#
""");
}
public override async Task Where_DateOnly_AddDays(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_DateOnly_AddDays(async));
await base.Where_DateOnly_AddDays(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEADD('d', CLNG(3), `m`.`Date`) = #1990-11-13#
""");
}
public override async Task Where_TimeOnly_Hour(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_TimeOnly_Hour(async));
await base.Where_TimeOnly_Hour(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEPART('h', `m`.`Time`) = 10
""");
}
public override async Task Where_TimeOnly_Minute(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_TimeOnly_Minute(async));
await base.Where_TimeOnly_Minute(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEPART('n', `m`.`Time`) = 15
""");
}
public override async Task Where_TimeOnly_Second(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_TimeOnly_Second(async));
await base.Where_TimeOnly_Second(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE DATEPART('s', `m`.`Time`) = 50
""");
}
public override async Task Where_TimeOnly_Millisecond(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_TimeOnly_Millisecond(async));
await base.Where_TimeOnly_Millisecond(async);
AssertSql();
AssertSql(
"""
SELECT [m].[Id], [m].[CodeName], [m].[Date], [m].[Duration], [m].[Rating], [m].[Time], [m].[Timeline]
FROM [Missions] AS [m]
WHERE DATEPART(millisecond, [m].[Time]) = 500
""");
}
public override async Task Where_TimeOnly_AddHours(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_TimeOnly_AddHours(async));
await base.Where_TimeOnly_AddHours(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE TIMEVALUE(DATEADD('h', CLNG(3.0), `m`.`Time`)) = TIMEVALUE('13:15:50')
""");
}
public override async Task Where_TimeOnly_AddMinutes(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_TimeOnly_AddMinutes(async));
await base.Where_TimeOnly_AddMinutes(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE TIMEVALUE(DATEADD('n', CLNG(3.0), `m`.`Time`)) = TIMEVALUE('10:18:50')
""");
}
public override async Task Where_TimeOnly_Add_TimeSpan(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_TimeOnly_Add_TimeSpan(async));
AssertSql();
@ -9379,15 +9429,18 @@ ORDER BY IIF(`t`.`GearNickName` IS NOT NULL, `t0`.`SquadId`, NULL), `t`.`Note`
public override async Task Where_TimeOnly_IsBetween(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_TimeOnly_IsBetween(async));
await base.Where_TimeOnly_IsBetween(async);
AssertSql();
AssertSql(
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE (IIF(`m`.`Time` >= TIMEVALUE('10:00:00'), TRUE, FALSE) BAND IIF(`m`.`Time` < TIMEVALUE('11:00:00'), TRUE, FALSE)) = TRUE
""");
}
public override async Task Where_TimeOnly_subtract_TimeOnly(bool async)
{
// DateOnly and TimeOnly. Issue #24507.
await AssertTranslationFailed(() => base.Where_TimeOnly_subtract_TimeOnly(async));
AssertSql();
@ -9674,19 +9727,27 @@ WHERE `f`.`ServerAddress` = '127.0.0.1'
await base.FirstOrDefault_on_empty_collection_of_DateTime_in_subquery(async);
AssertSql(
"""
SELECT [g].[Nickname], COALESCE((
SELECT TOP(1) [t1].[IssueDate]
FROM [Tags] AS [t1]
WHERE [t1].[GearNickName] = [g].[FullName]
ORDER BY [t1].[Id]), '0001-01-01T00:00:00.0000000') AS [invalidTagIssueDate]
FROM [Gears] AS [g]
LEFT JOIN [Tags] AS [t] ON [g].[Nickname] = [t].[GearNickName] AND [g].[SquadId] = [t].[GearSquadId]
WHERE [t].[IssueDate] > COALESCE((
SELECT TOP(1) [t0].[IssueDate]
FROM [Tags] AS [t0]
WHERE [t0].[GearNickName] = [g].[FullName]
ORDER BY [t0].[Id]), '0001-01-01T00:00:00.0000000')
"""
SELECT `g`.`Nickname`, IIF((
SELECT TOP 1 `t1`.`IssueDate`
FROM `Tags` AS `t1`
WHERE `t1`.`GearNickName` = `g`.`FullName`
ORDER BY `t1`.`Id`) IS NULL, #1899-12-30#, (
SELECT TOP 1 `t1`.`IssueDate`
FROM `Tags` AS `t1`
WHERE `t1`.`GearNickName` = `g`.`FullName`
ORDER BY `t1`.`Id`)) AS `invalidTagIssueDate`
FROM `Gears` AS `g`
LEFT JOIN `Tags` AS `t` ON `g`.`Nickname` = `t`.`GearNickName` AND `g`.`SquadId` = `t`.`GearSquadId`
WHERE `t`.`IssueDate` > IIF((
SELECT TOP 1 `t0`.`IssueDate`
FROM `Tags` AS `t0`
WHERE `t0`.`GearNickName` = `g`.`FullName`
ORDER BY `t0`.`Id`) IS NULL, #1899-12-30#, (
SELECT TOP 1 `t0`.`IssueDate`
FROM `Tags` AS `t0`
WHERE `t0`.`GearNickName` = `g`.`FullName`
ORDER BY `t0`.`Id`))
""");
}
@ -9825,10 +9886,10 @@ ORDER BY [g].[Nickname], [g].[SquadId]
await base.Where_equals_method_on_nullable_with_object_overload(async);
AssertSql(
"""
SELECT [m].[Id], [m].[CodeName], [m].[Duration], [m].[Rating], [m].[Timeline]
FROM [Missions] AS [m]
WHERE [m].[Rating] IS NULL
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE `m`.`Rating` IS NULL
""");
}

Loading…
Cancel
Save