Properly read a TimeSpan value from the database.

Add member translator for timespan so SQL works
pull/137/head
Christopher Jolly 3 years ago
parent 096a0955e2
commit d7033125be

@ -356,5 +356,23 @@ namespace EntityFrameworkCore.Jet.Data
public override object this[int ordinal]
=> _wrappedDataReader[ordinal];
public override T GetFieldValue<T>(int ordinal)
{
if (typeof(T) == typeof(DateTime))
{
return (T)(object)GetDateTime(ordinal);
}
if (typeof(T) == typeof(TimeSpan))
{
return (T)(object)GetTimeSpan(ordinal);
}
if (typeof(T) == typeof(DateTimeOffset))
{
return (T)(object)GetDateTimeOffset(ordinal);
}
return (T)GetValue(ordinal);
}
}
}

@ -25,6 +25,7 @@ namespace EntityFrameworkCore.Jet.Query.ExpressionTranslators.Internal
{
new JetStringMemberTranslator(sqlExpressionFactory),
new JetDateTimeMemberTranslator(sqlExpressionFactory),
new JetTimeSpanMemberTranslator(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 JetTimeSpanMemberTranslator : IMemberTranslator
{
private static readonly Dictionary<string, string> DatePartMappings = new()
{
{ nameof(TimeSpan.Hours), "h" },
{ nameof(TimeSpan.Minutes), "n" },
{ nameof(TimeSpan.Seconds), "s" },
{ nameof(TimeSpan.Milliseconds), "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 JetTimeSpanMemberTranslator(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(TimeSpan) && 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;
}
}
Loading…
Cancel
Save