tgstation-server 6.16.0
The /tg/station 13 server suite
Loading...
Searching...
No Matches
SqliteDatabaseContext.cs
Go to the documentation of this file.
1using System;
2using System.Linq;
3
4using Microsoft.EntityFrameworkCore;
5using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
6
8
10{
15 {
19 readonly bool designTime;
20
26 DbContextOptions<SqliteDatabaseContext> dbContextOptions)
27 : this(dbContextOptions, false)
28 {
29 }
30
36 internal SqliteDatabaseContext(
37 DbContextOptions<SqliteDatabaseContext> dbContextOptions,
38 bool designTime)
39 : base(dbContextOptions)
40 {
41 this.designTime = designTime;
42 }
43
49 public static void ConfigureWith(
50 DbContextOptionsBuilder options,
51 DatabaseConfiguration databaseConfiguration)
52 {
53 ArgumentNullException.ThrowIfNull(options);
54 ArgumentNullException.ThrowIfNull(databaseConfiguration);
55
56 if (databaseConfiguration.DatabaseType != DatabaseType.Sqlite)
57 throw new InvalidOperationException($"Invalid DatabaseType for {nameof(SqliteDatabaseContext)}!");
58
59 options.UseSqlite(databaseConfiguration.ConnectionString, sqliteOptions =>
60 {
61 sqliteOptions.TranslateParameterizedCollectionsToConstants();
62 sqliteOptions.UseQuerySplittingBehavior(QuerySplittingBehavior.SingleQuery);
63 });
64 }
65
67 protected override void OnModelCreating(ModelBuilder modelBuilder)
68 {
69 base.OnModelCreating(modelBuilder);
70
71 // Shamelessly stolen from https://blog.dangl.me/archive/handling-datetimeoffset-in-sqlite-with-entity-framework-core/
72
73 // SQLite does not have proper support for DateTimeOffset via Entity Framework Core, see the limitations
74 // here: https://docs.microsoft.com/en-us/ef/core/providers/sqlite/limitations#query-limitations
75 // To work around this, when the Sqlite database provider is used, all model properties of type DateTimeOffset
76 // use the DateTimeOffsetToBinaryConverter
77 // Based on: https://github.com/aspnet/EntityFrameworkCore/issues/10784#issuecomment-415769754
78 // This only supports millisecond precision, but should be sufficient for most use cases.
79 foreach (var entityType in modelBuilder.Model.GetEntityTypes())
80 {
81 var properties = entityType
82 .ClrType
83 .GetProperties()
84 .Where(p => p.PropertyType == typeof(DateTimeOffset) || p.PropertyType == typeof(DateTimeOffset?));
85 foreach (var property in properties)
86 modelBuilder
87 .Entity(entityType.Name)
88 .Property(property.Name)
89 .HasConversion(new DateTimeOffsetToBinaryConverter())
90 .HasColumnType("TEXT"); // Dominion: This is for purely legacy reasons
91 }
92 }
93 }
94}
Configuration options for the Database.DatabaseContext.
string? ConnectionString
The connection string for the database.
DatabaseType DatabaseType
The Configuration.DatabaseType to create.
Backend abstract implementation of IDatabaseContext.
SqliteDatabaseContext(DbContextOptions< SqliteDatabaseContext > dbContextOptions)
Initializes a new instance of the SqliteDatabaseContext class.
readonly bool designTime
If the database context is running in design time mode.
static void ConfigureWith(DbContextOptionsBuilder options, DatabaseConfiguration databaseConfiguration)
Configure the SqliteDatabaseContext.
override void OnModelCreating(ModelBuilder modelBuilder)
DatabaseType
Type of database to user.