Fix efcore not returning a UTC DateTime

This commit is contained in:
crobibero 2020-11-25 07:44:11 -07:00
parent 3d6920ae40
commit 6c0188c42b
5 changed files with 71 additions and 25 deletions

View File

@ -1,5 +1,6 @@
#pragma warning disable CS1591
using System;
using System.Linq;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Interfaces;
@ -140,6 +141,7 @@ namespace Jellyfin.Server.Implementations
/// <inheritdoc />
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.SetDefaultDateTimeKind(DateTimeKind.Utc);
base.OnModelCreating(modelBuilder);
modelBuilder.HasDefaultSchema("jellyfin");

View File

@ -0,0 +1,48 @@
using System;
using Jellyfin.Server.Implementations.ValueConverters;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace Jellyfin.Server.Implementations
{
/// <summary>
/// Model builder extensions.
/// </summary>
public static class ModelBuilderExtensions
{
/// <summary>
/// Specify value converter for the object type.
/// </summary>
/// <param name="modelBuilder">The model builder.</param>
/// <param name="converter">The <see cref="ValueConverter{TModel,TProvider}"/>.</param>
/// <typeparam name="T">The type to convert.</typeparam>
/// <returns>The modified <see cref="ModelBuilder"/>.</returns>
public static ModelBuilder UseValueConverterForType<T>(this ModelBuilder modelBuilder, ValueConverter converter)
{
var type = typeof(T);
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
foreach (var property in entityType.GetProperties())
{
if (property.ClrType == type)
{
property.SetValueConverter(converter);
}
}
}
return modelBuilder;
}
/// <summary>
/// Specify the default <see cref="DateTimeKind"/>.
/// </summary>
/// <param name="modelBuilder">The model builder to extend.</param>
/// <param name="kind">The <see cref="DateTimeKind"/> to specify.</param>
public static void SetDefaultDateTimeKind(this ModelBuilder modelBuilder, DateTimeKind kind)
{
modelBuilder.UseValueConverterForType<DateTime>(new DateTimeKindValueConverter(kind));
modelBuilder.UseValueConverterForType<DateTime?>(new DateTimeKindValueConverter(kind));
}
}
}

View File

@ -0,0 +1,21 @@
using System;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace Jellyfin.Server.Implementations.ValueConverters
{
/// <summary>
/// ValueConverter to specify kind.
/// </summary>
public class DateTimeKindValueConverter : ValueConverter<DateTime, DateTime>
{
/// <summary>
/// Initializes a new instance of the <see cref="DateTimeKindValueConverter"/> class.
/// </summary>
/// <param name="kind">The kind to specify.</param>
/// <param name="mappingHints">The mapping hints.</param>
public DateTimeKindValueConverter(DateTimeKind kind, ConverterMappingHints mappingHints = null)
: base(v => v.ToUniversalTime(), v => DateTime.SpecifyKind(v, kind), mappingHints)
{
}
}
}

View File

@ -1,24 +0,0 @@
using System;
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace MediaBrowser.Common.Json.Converters
{
/// <summary>
/// Returns an ISO8601 formatted datetime.
/// </summary>
/// <remarks>
/// Used for legacy compatibility.
/// </remarks>
public class JsonDateTimeIso8601Converter : JsonConverter<DateTime>
{
/// <inheritdoc />
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
=> reader.GetDateTime();
/// <inheritdoc />
public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
=> writer.WriteStringValue(value.ToString("O", CultureInfo.InvariantCulture));
}
}

View File

@ -43,7 +43,6 @@ namespace MediaBrowser.Common.Json
options.Converters.Add(new JsonVersionConverter());
options.Converters.Add(new JsonStringEnumConverter());
options.Converters.Add(new JsonNullableStructConverterFactory());
options.Converters.Add(new JsonDateTimeIso8601Converter());
return options;
}