using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Mizuki.Database.Models; namespace Mizuki.Database; /// /// The DB context for Mizuki. /// public class MizukiDbContext : DbContext { /// /// The users. /// public virtual DbSet Users { get; set; } = null!; /// /// The files. /// public virtual DbSet Uploads { get; set; } = null!; /// protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity(); modelBuilder.Entity(); if (Database.ProviderName == "Microsoft.EntityFrameworkCore.Sqlite") { // SQLite does not have proper support for DateTimeOffset via Entity Framework Core, see the limitations // here: https://docs.microsoft.com/en-us/ef/core/providers/sqlite/limitations#query-limitations // To work around this, when the Sqlite database provider is used, all model properties of type DateTimeOffset // use the DateTimeOffsetToBinaryConverter // Based on: https://github.com/aspnet/EntityFrameworkCore/issues/10784#issuecomment-415769754 // This only supports millisecond precision, but should be sufficient for most use cases. foreach (var entityType in modelBuilder.Model.GetEntityTypes()) { var properties = entityType.ClrType.GetProperties().Where(p => p.PropertyType == typeof(DateTimeOffset) || p.PropertyType == typeof(DateTimeOffset?)); foreach (var property in properties) { modelBuilder .Entity(entityType.Name) .Property(property.Name) .HasConversion(new DateTimeOffsetToBinaryConverter()); } } } } /// protected override void OnConfiguring(DbContextOptionsBuilder options) => options.UseSqlite($"Data Source=mizuki.db"); }