diff --git a/OptixServe.Api/OptixServe.Api.csproj b/OptixServe.Api/OptixServe.Api.csproj
index 79d3b79..88bb489 100644
--- a/OptixServe.Api/OptixServe.Api.csproj
+++ b/OptixServe.Api/OptixServe.Api.csproj
@@ -16,7 +16,7 @@
enable
enable
true
- false
+ true
diff --git a/OptixServe.Infrastructure/Data/CompiledModels/AppDbContextAssemblyAttributes.cs b/OptixServe.Infrastructure/Data/CompiledModels/AppDbContextAssemblyAttributes.cs
new file mode 100644
index 0000000..1e19b39
--- /dev/null
+++ b/OptixServe.Infrastructure/Data/CompiledModels/AppDbContextAssemblyAttributes.cs
@@ -0,0 +1,9 @@
+//
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using OptixServe.Infrastructure.Data;
+using OptixServe.Infrastructure.Data.CompiledModels;
+
+#pragma warning disable 219, 612, 618
+#nullable disable
+
+[assembly: DbContextModel(typeof(AppDbContext), typeof(AppDbContextModel))]
diff --git a/OptixServe.Infrastructure/Data/CompiledModels/AppDbContextModel.cs b/OptixServe.Infrastructure/Data/CompiledModels/AppDbContextModel.cs
new file mode 100644
index 0000000..e39c666
--- /dev/null
+++ b/OptixServe.Infrastructure/Data/CompiledModels/AppDbContextModel.cs
@@ -0,0 +1,47 @@
+//
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+
+#pragma warning disable 219, 612, 618
+#nullable disable
+
+namespace OptixServe.Infrastructure.Data.CompiledModels
+{
+ [DbContext(typeof(AppDbContext))]
+ public partial class AppDbContextModel : RuntimeModel
+ {
+ private static readonly bool _useOldBehavior31751 =
+ System.AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue31751", out var enabled31751) && enabled31751;
+
+ static AppDbContextModel()
+ {
+ var model = new AppDbContextModel();
+
+ if (_useOldBehavior31751)
+ {
+ model.Initialize();
+ }
+ else
+ {
+ var thread = new System.Threading.Thread(RunInitialization, 10 * 1024 * 1024);
+ thread.Start();
+ thread.Join();
+
+ void RunInitialization()
+ {
+ model.Initialize();
+ }
+ }
+
+ model.Customize();
+ _instance = (AppDbContextModel)model.FinalizeModel();
+ }
+
+ private static AppDbContextModel _instance;
+ public static IModel Instance => _instance;
+
+ partial void Initialize();
+
+ partial void Customize();
+ }
+}
diff --git a/OptixServe.Infrastructure/Data/CompiledModels/AppDbContextModelBuilder.cs b/OptixServe.Infrastructure/Data/CompiledModels/AppDbContextModelBuilder.cs
new file mode 100644
index 0000000..c2b61a7
--- /dev/null
+++ b/OptixServe.Infrastructure/Data/CompiledModels/AppDbContextModelBuilder.cs
@@ -0,0 +1,99 @@
+//
+using System;
+using System.Collections.Generic;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Metadata.Internal;
+using Microsoft.EntityFrameworkCore.Update.Internal;
+
+#pragma warning disable 219, 612, 618
+#nullable disable
+
+namespace OptixServe.Infrastructure.Data.CompiledModels
+{
+ public partial class AppDbContextModel
+ {
+ private AppDbContextModel()
+ : base(skipDetectChanges: false, modelId: new Guid("3214a553-d69f-4844-a587-080f6d463671"), entityTypeCount: 1)
+ {
+ }
+
+ partial void Initialize()
+ {
+ var user = UserEntityType.Create(this);
+
+ UserEntityType.CreateAnnotations(user);
+
+ AddAnnotation("ProductVersion", "9.0.6");
+ AddRuntimeAnnotation("Relational:RelationalModelFactory", () => CreateRelationalModel());
+ }
+
+ private IRelationalModel CreateRelationalModel()
+ {
+ var relationalModel = new RelationalModel(this);
+
+ var user = FindEntityType("OptixServe.Core.Models.User")!;
+
+ var defaultTableMappings = new List>();
+ user.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings);
+ var optixServeCoreModelsUserTableBase = new TableBase("OptixServe.Core.Models.User", null, relationalModel);
+ var idColumnBase = new ColumnBase("Id", "TEXT", optixServeCoreModelsUserTableBase);
+ optixServeCoreModelsUserTableBase.Columns.Add("Id", idColumnBase);
+ var passwordColumnBase = new ColumnBase("Password", "TEXT", optixServeCoreModelsUserTableBase)
+ {
+ IsNullable = true
+ };
+ optixServeCoreModelsUserTableBase.Columns.Add("Password", passwordColumnBase);
+ var privilegeGroupColumnBase = new ColumnBase("PrivilegeGroup", "INTEGER", optixServeCoreModelsUserTableBase);
+ optixServeCoreModelsUserTableBase.Columns.Add("PrivilegeGroup", privilegeGroupColumnBase);
+ var userNameColumnBase = new ColumnBase("UserName", "TEXT", optixServeCoreModelsUserTableBase);
+ optixServeCoreModelsUserTableBase.Columns.Add("UserName", userNameColumnBase);
+ relationalModel.DefaultTables.Add("OptixServe.Core.Models.User", optixServeCoreModelsUserTableBase);
+ var optixServeCoreModelsUserMappingBase = new TableMappingBase(user, optixServeCoreModelsUserTableBase, null);
+ optixServeCoreModelsUserTableBase.AddTypeMapping(optixServeCoreModelsUserMappingBase, false);
+ defaultTableMappings.Add(optixServeCoreModelsUserMappingBase);
+ RelationalModel.CreateColumnMapping((ColumnBase)idColumnBase, user.FindProperty("Id")!, optixServeCoreModelsUserMappingBase);
+ RelationalModel.CreateColumnMapping((ColumnBase)passwordColumnBase, user.FindProperty("Password")!, optixServeCoreModelsUserMappingBase);
+ RelationalModel.CreateColumnMapping((ColumnBase)privilegeGroupColumnBase, user.FindProperty("PrivilegeGroup")!, optixServeCoreModelsUserMappingBase);
+ RelationalModel.CreateColumnMapping((ColumnBase)userNameColumnBase, user.FindProperty("UserName")!, optixServeCoreModelsUserMappingBase);
+
+ var tableMappings = new List();
+ user.SetRuntimeAnnotation("Relational:TableMappings", tableMappings);
+ var usersTable = new Table("Users", null, relationalModel);
+ var idColumn = new Column("Id", "TEXT", usersTable);
+ usersTable.Columns.Add("Id", idColumn);
+ idColumn.Accessors = ColumnAccessorsFactory.CreateGeneric(idColumn);
+ var passwordColumn = new Column("Password", "TEXT", usersTable)
+ {
+ IsNullable = true
+ };
+ usersTable.Columns.Add("Password", passwordColumn);
+ passwordColumn.Accessors = ColumnAccessorsFactory.CreateGeneric(passwordColumn);
+ var privilegeGroupColumn = new Column("PrivilegeGroup", "INTEGER", usersTable);
+ usersTable.Columns.Add("PrivilegeGroup", privilegeGroupColumn);
+ privilegeGroupColumn.Accessors = ColumnAccessorsFactory.CreateGeneric(privilegeGroupColumn);
+ var userNameColumn = new Column("UserName", "TEXT", usersTable);
+ usersTable.Columns.Add("UserName", userNameColumn);
+ userNameColumn.Accessors = ColumnAccessorsFactory.CreateGeneric(userNameColumn);
+ relationalModel.Tables.Add(("Users", null), usersTable);
+ var usersTableMapping = new TableMapping(user, usersTable, null);
+ usersTable.AddTypeMapping(usersTableMapping, false);
+ tableMappings.Add(usersTableMapping);
+ RelationalModel.CreateColumnMapping(idColumn, user.FindProperty("Id")!, usersTableMapping);
+ RelationalModel.CreateColumnMapping(passwordColumn, user.FindProperty("Password")!, usersTableMapping);
+ RelationalModel.CreateColumnMapping(privilegeGroupColumn, user.FindProperty("PrivilegeGroup")!, usersTableMapping);
+ RelationalModel.CreateColumnMapping(userNameColumn, user.FindProperty("UserName")!, usersTableMapping);
+ var pK_Users = new UniqueConstraint("PK_Users", usersTable, new[] { idColumn });
+ usersTable.PrimaryKey = pK_Users;
+ pK_Users.SetRowKeyValueFactory(new SimpleRowKeyValueFactory(pK_Users));
+ var pK_UsersKey = RelationalModel.GetKey(this,
+ "OptixServe.Core.Models.User",
+ new[] { "Id" });
+ pK_Users.MappedKeys.Add(pK_UsersKey);
+ RelationalModel.GetOrCreateUniqueConstraints(pK_UsersKey).Add(pK_Users);
+ usersTable.UniqueConstraints.Add("PK_Users", pK_Users);
+ return relationalModel.MakeReadOnly();
+ }
+ }
+}
diff --git a/OptixServe.Infrastructure/Data/CompiledModels/UserEntityType.cs b/OptixServe.Infrastructure/Data/CompiledModels/UserEntityType.cs
new file mode 100644
index 0000000..ec6b122
--- /dev/null
+++ b/OptixServe.Infrastructure/Data/CompiledModels/UserEntityType.cs
@@ -0,0 +1,227 @@
+//
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using Microsoft.EntityFrameworkCore.ChangeTracking;
+using Microsoft.EntityFrameworkCore.ChangeTracking.Internal;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Metadata.Internal;
+using Microsoft.EntityFrameworkCore.Sqlite.Storage.Internal;
+using Microsoft.EntityFrameworkCore.Storage;
+using Microsoft.EntityFrameworkCore.Storage.Json;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using OptixServe.Core.Models;
+
+#pragma warning disable 219, 612, 618
+#nullable disable
+
+namespace OptixServe.Infrastructure.Data.CompiledModels
+{
+ [EntityFrameworkInternal]
+ public partial class UserEntityType
+ {
+ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null)
+ {
+ var runtimeEntityType = model.AddEntityType(
+ "OptixServe.Core.Models.User",
+ typeof(User),
+ baseEntityType,
+ propertyCount: 4,
+ keyCount: 1);
+
+ var id = runtimeEntityType.AddProperty(
+ "Id",
+ typeof(string),
+ propertyInfo: typeof(User).GetProperty("Id", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly),
+ fieldInfo: typeof(User).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly),
+ afterSaveBehavior: PropertySaveBehavior.Throw);
+ id.SetGetter(
+ string (User entity) => UserUnsafeAccessors.Id(entity),
+ bool (User entity) => UserUnsafeAccessors.Id(entity) == null,
+ string (User instance) => UserUnsafeAccessors.Id(instance),
+ bool (User instance) => UserUnsafeAccessors.Id(instance) == null);
+ id.SetSetter(
+ (User entity, string value) => UserUnsafeAccessors.Id(entity) = value);
+ id.SetMaterializationSetter(
+ (User entity, string value) => UserUnsafeAccessors.Id(entity) = value);
+ id.SetAccessors(
+ string (InternalEntityEntry entry) => UserUnsafeAccessors.Id(((User)(entry.Entity))),
+ string (InternalEntityEntry entry) => UserUnsafeAccessors.Id(((User)(entry.Entity))),
+ string (InternalEntityEntry entry) => entry.ReadOriginalValue(id, 0),
+ string (InternalEntityEntry entry) => entry.ReadRelationshipSnapshotValue(id, 0),
+ object (ValueBuffer valueBuffer) => valueBuffer[0]);
+ id.SetPropertyIndexes(
+ index: 0,
+ originalValueIndex: 0,
+ shadowIndex: -1,
+ relationshipIndex: 0,
+ storeGenerationIndex: -1);
+ id.TypeMapping = SqliteStringTypeMapping.Default;
+ id.SetCurrentValueComparer(new EntryCurrentValueComparer(id));
+
+ var password = runtimeEntityType.AddProperty(
+ "Password",
+ typeof(string),
+ propertyInfo: typeof(User).GetProperty("Password", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly),
+ fieldInfo: typeof(User).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly),
+ nullable: true);
+ password.SetGetter(
+ string (User entity) => UserUnsafeAccessors.Password(entity),
+ bool (User entity) => UserUnsafeAccessors.Password(entity) == null,
+ string (User instance) => UserUnsafeAccessors.Password(instance),
+ bool (User instance) => UserUnsafeAccessors.Password(instance) == null);
+ password.SetSetter(
+ (User entity, string value) => UserUnsafeAccessors.Password(entity) = value);
+ password.SetMaterializationSetter(
+ (User entity, string value) => UserUnsafeAccessors.Password(entity) = value);
+ password.SetAccessors(
+ string (InternalEntityEntry entry) => UserUnsafeAccessors.Password(((User)(entry.Entity))),
+ string (InternalEntityEntry entry) => UserUnsafeAccessors.Password(((User)(entry.Entity))),
+ string (InternalEntityEntry entry) => entry.ReadOriginalValue(password, 1),
+ string (InternalEntityEntry entry) => entry.GetCurrentValue(password),
+ object (ValueBuffer valueBuffer) => valueBuffer[1]);
+ password.SetPropertyIndexes(
+ index: 1,
+ originalValueIndex: 1,
+ shadowIndex: -1,
+ relationshipIndex: -1,
+ storeGenerationIndex: -1);
+ password.TypeMapping = SqliteStringTypeMapping.Default;
+
+ var privilegeGroup = runtimeEntityType.AddProperty(
+ "PrivilegeGroup",
+ typeof(PrivilegeGroup),
+ propertyInfo: typeof(User).GetProperty("PrivilegeGroup", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly),
+ fieldInfo: typeof(User).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly));
+ privilegeGroup.SetGetter(
+ PrivilegeGroup (User entity) => UserUnsafeAccessors.PrivilegeGroup(entity),
+ bool (User entity) => object.Equals(((object)(UserUnsafeAccessors.PrivilegeGroup(entity))), ((object)(PrivilegeGroup.Admin))),
+ PrivilegeGroup (User instance) => UserUnsafeAccessors.PrivilegeGroup(instance),
+ bool (User instance) => object.Equals(((object)(UserUnsafeAccessors.PrivilegeGroup(instance))), ((object)(PrivilegeGroup.Admin))));
+ privilegeGroup.SetSetter(
+ (User entity, PrivilegeGroup value) => UserUnsafeAccessors.PrivilegeGroup(entity) = value);
+ privilegeGroup.SetMaterializationSetter(
+ (User entity, PrivilegeGroup value) => UserUnsafeAccessors.PrivilegeGroup(entity) = value);
+ privilegeGroup.SetAccessors(
+ PrivilegeGroup (InternalEntityEntry entry) => UserUnsafeAccessors.PrivilegeGroup(((User)(entry.Entity))),
+ PrivilegeGroup (InternalEntityEntry entry) => UserUnsafeAccessors.PrivilegeGroup(((User)(entry.Entity))),
+ PrivilegeGroup (InternalEntityEntry entry) => entry.ReadOriginalValue(privilegeGroup, 2),
+ PrivilegeGroup (InternalEntityEntry entry) => entry.GetCurrentValue(privilegeGroup),
+ object (ValueBuffer valueBuffer) => valueBuffer[2]);
+ privilegeGroup.SetPropertyIndexes(
+ index: 2,
+ originalValueIndex: 2,
+ shadowIndex: -1,
+ relationshipIndex: -1,
+ storeGenerationIndex: -1);
+ privilegeGroup.TypeMapping = IntTypeMapping.Default.Clone(
+ comparer: new ValueComparer(
+ bool (PrivilegeGroup v1, PrivilegeGroup v2) => object.Equals(((object)(v1)), ((object)(v2))),
+ int (PrivilegeGroup v) => ((object)v).GetHashCode(),
+ PrivilegeGroup (PrivilegeGroup v) => v),
+ keyComparer: new ValueComparer(
+ bool (PrivilegeGroup v1, PrivilegeGroup v2) => object.Equals(((object)(v1)), ((object)(v2))),
+ int (PrivilegeGroup v) => ((object)v).GetHashCode(),
+ PrivilegeGroup (PrivilegeGroup v) => v),
+ providerValueComparer: new ValueComparer(
+ bool (int v1, int v2) => v1 == v2,
+ int (int v) => v,
+ int (int v) => v),
+ mappingInfo: new RelationalTypeMappingInfo(
+ storeTypeName: "INTEGER"),
+ converter: new ValueConverter(
+ int (PrivilegeGroup value) => ((int)(value)),
+ PrivilegeGroup (int value) => ((PrivilegeGroup)(value))),
+ jsonValueReaderWriter: new JsonConvertedValueReaderWriter(
+ JsonInt32ReaderWriter.Instance,
+ new ValueConverter(
+ int (PrivilegeGroup value) => ((int)(value)),
+ PrivilegeGroup (int value) => ((PrivilegeGroup)(value)))));
+ privilegeGroup.SetSentinelFromProviderValue(0);
+
+ var userName = runtimeEntityType.AddProperty(
+ "UserName",
+ typeof(string),
+ propertyInfo: typeof(User).GetProperty("UserName", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly),
+ fieldInfo: typeof(User).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly));
+ userName.SetGetter(
+ string (User entity) => UserUnsafeAccessors.UserName(entity),
+ bool (User entity) => UserUnsafeAccessors.UserName(entity) == null,
+ string (User instance) => UserUnsafeAccessors.UserName(instance),
+ bool (User instance) => UserUnsafeAccessors.UserName(instance) == null);
+ userName.SetSetter(
+ (User entity, string value) => UserUnsafeAccessors.UserName(entity) = value);
+ userName.SetMaterializationSetter(
+ (User entity, string value) => UserUnsafeAccessors.UserName(entity) = value);
+ userName.SetAccessors(
+ string (InternalEntityEntry entry) => UserUnsafeAccessors.UserName(((User)(entry.Entity))),
+ string (InternalEntityEntry entry) => UserUnsafeAccessors.UserName(((User)(entry.Entity))),
+ string (InternalEntityEntry entry) => entry.ReadOriginalValue(userName, 3),
+ string (InternalEntityEntry entry) => entry.GetCurrentValue(userName),
+ object (ValueBuffer valueBuffer) => valueBuffer[3]);
+ userName.SetPropertyIndexes(
+ index: 3,
+ originalValueIndex: 3,
+ shadowIndex: -1,
+ relationshipIndex: -1,
+ storeGenerationIndex: -1);
+ userName.TypeMapping = SqliteStringTypeMapping.Default;
+
+ var key = runtimeEntityType.AddKey(
+ new[] { id });
+ runtimeEntityType.SetPrimaryKey(key);
+
+ return runtimeEntityType;
+ }
+
+ public static void CreateAnnotations(RuntimeEntityType runtimeEntityType)
+ {
+ var id = runtimeEntityType.FindProperty("Id");
+ var password = runtimeEntityType.FindProperty("Password");
+ var privilegeGroup = runtimeEntityType.FindProperty("PrivilegeGroup");
+ var userName = runtimeEntityType.FindProperty("UserName");
+ var key = runtimeEntityType.FindKey(new[] { id });
+ key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNullableFactory(key));
+ key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key));
+ runtimeEntityType.SetOriginalValuesFactory(
+ ISnapshot (InternalEntityEntry source) =>
+ {
+ var entity = ((User)(source.Entity));
+ return ((ISnapshot)(new Snapshot((source.GetCurrentValue(id) == null ? null : ((ValueComparer)(((IProperty)id).GetValueComparer())).Snapshot(source.GetCurrentValue(id))), (source.GetCurrentValue(password) == null ? null : ((ValueComparer)(((IProperty)password).GetValueComparer())).Snapshot(source.GetCurrentValue(password))), ((ValueComparer)(((IProperty)privilegeGroup).GetValueComparer())).Snapshot(source.GetCurrentValue(privilegeGroup)), (source.GetCurrentValue(userName) == null ? null : ((ValueComparer)(((IProperty)userName).GetValueComparer())).Snapshot(source.GetCurrentValue(userName))))));
+ });
+ runtimeEntityType.SetStoreGeneratedValuesFactory(
+ ISnapshot () => Snapshot.Empty);
+ runtimeEntityType.SetTemporaryValuesFactory(
+ ISnapshot (InternalEntityEntry source) => Snapshot.Empty);
+ runtimeEntityType.SetShadowValuesFactory(
+ ISnapshot (IDictionary source) => Snapshot.Empty);
+ runtimeEntityType.SetEmptyShadowValuesFactory(
+ ISnapshot () => Snapshot.Empty);
+ runtimeEntityType.SetRelationshipSnapshotFactory(
+ ISnapshot (InternalEntityEntry source) =>
+ {
+ var entity = ((User)(source.Entity));
+ return ((ISnapshot)(new Snapshot((source.GetCurrentValue(id) == null ? null : ((ValueComparer)(((IProperty)id).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(id))))));
+ });
+ runtimeEntityType.Counts = new PropertyCounts(
+ propertyCount: 4,
+ navigationCount: 0,
+ complexPropertyCount: 0,
+ originalValueCount: 4,
+ shadowCount: 0,
+ relationshipCount: 1,
+ storeGeneratedCount: 0);
+ runtimeEntityType.AddAnnotation("Relational:FunctionName", null);
+ runtimeEntityType.AddAnnotation("Relational:Schema", null);
+ runtimeEntityType.AddAnnotation("Relational:SqlQuery", null);
+ runtimeEntityType.AddAnnotation("Relational:TableName", "Users");
+ runtimeEntityType.AddAnnotation("Relational:ViewName", null);
+ runtimeEntityType.AddAnnotation("Relational:ViewSchema", null);
+
+ Customize(runtimeEntityType);
+ }
+
+ static partial void Customize(RuntimeEntityType runtimeEntityType);
+ }
+}
diff --git a/OptixServe.Infrastructure/Data/CompiledModels/UserUnsafeAccessors.cs b/OptixServe.Infrastructure/Data/CompiledModels/UserUnsafeAccessors.cs
new file mode 100644
index 0000000..7ce25c7
--- /dev/null
+++ b/OptixServe.Infrastructure/Data/CompiledModels/UserUnsafeAccessors.cs
@@ -0,0 +1,25 @@
+//
+using System;
+using System.Runtime.CompilerServices;
+using OptixServe.Core.Models;
+
+#pragma warning disable 219, 612, 618
+#nullable disable
+
+namespace OptixServe.Infrastructure.Data.CompiledModels
+{
+ public static class UserUnsafeAccessors
+ {
+ [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "k__BackingField")]
+ public static extern ref string Id(User @this);
+
+ [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "k__BackingField")]
+ public static extern ref string Password(User @this);
+
+ [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "k__BackingField")]
+ public static extern ref PrivilegeGroup PrivilegeGroup(User @this);
+
+ [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "k__BackingField")]
+ public static extern ref string UserName(User @this);
+ }
+}
diff --git a/OptixServe.Infrastructure/EFCore-NativeAOT-Intergration.md b/OptixServe.Infrastructure/EFCore-NativeAOT-Intergration.md
new file mode 100644
index 0000000..43eb346
--- /dev/null
+++ b/OptixServe.Infrastructure/EFCore-NativeAOT-Intergration.md
@@ -0,0 +1,82 @@
+# EFCore Intergration
+
+## Introduction
+
+This app relies on EF Core to access the database.
+
+However, it is NOT so smooth when work with NativeAOT.
+
+To use EF Core, see below.
+
+## DesignTimeDbContextFactory
+
+To work with NativeAOT, a code-defined way to create DbContext instance is a MUST in nearly ALL operations of EF Core, letting ef tool discover the DbContext.
+
+In this project, `OptixServe.Infrastructure/Utilites/DesignTimeDbContextFactory.cs` is set up to do this.
+
+This class implements a simple commandline arguments parser, enabling passing arguments along with `dotnet ef`.
+
+Currently, there are two options, `--config/-c` and `--data-dir/-d` are supported. See documents there.
+
+To pass arguments/options to `CreateDbContext` static method, pass the arguments following with `dotnet ef` command, with two dashes splitting.
+
+For example:
+
+```bash
+dotnet ef database update -- -c ../data/appsettings.Development.json -d ../data/
+```
+
+## Workflow
+
+To make the code work, following the steps:
+
+1. Implement other parts
+2. Compile the data models, with `--nativeaot` option.
+3. Add migration
+4. Update database
+5. Build project, and Run!
+
+Here are the details.
+
+### Requirements
+
+See [https://learn.microsoft.com/en-us/ef/core/performance/nativeaot-and-precompiled-queries]()
+
+### Compile Models
+
+```bash
+dotnet ef dbcontext optimize --output-dir Data/CompiledModels --precompile-queries --nativeaot -- -c ../data_dev/appsettings.Development.json -d ../data_dev/
+```
+
+If this is the first time to run `dbcontext optimize`, DO NOT forget to `UseModel` in DbContext construction.
+
+```cs OptixServe.Infrastructure/Utilites/DatabaseHelper.cs
+public static void ConfigureDbContext(DbContextOptionsBuilder options)
+{
+ // ...
+ options.UseSqlite(connectionString, b => b.MigrationsAssembly("OptixServe.Infrastructure"))
+ .UseModel(AppDbContextModel.Instance);
+ // ...
+}
+```
+
+
+### Add Migration
+
+```bash
+dotnet ef migrations add InitialCreate -- -c ../data_dev/appsettings.Development.json
+```
+
+
+### Update Database
+
+```bash
+dotnet ef database update -- -c ../data_dev/appsettings.Development.json -d ../data_dev/
+```
+
+
+### Build Project
+
+```bash
+dotnet publish -c Release -r linux-x64
+```
\ No newline at end of file
diff --git a/OptixServe.Infrastructure/OptixServe.Infrastructure.csproj b/OptixServe.Infrastructure/OptixServe.Infrastructure.csproj
index 4f4b623..3e0efe0 100644
--- a/OptixServe.Infrastructure/OptixServe.Infrastructure.csproj
+++ b/OptixServe.Infrastructure/OptixServe.Infrastructure.csproj
@@ -9,6 +9,10 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
all
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
@@ -20,6 +24,7 @@
net9.0
enable
enable
+ $(InterceptorsNamespaces);Microsoft.EntityFrameworkCore.GeneratedInterceptors
diff --git a/OptixServe.Infrastructure/Utilites/DatabaseHelper.cs b/OptixServe.Infrastructure/Utilites/DatabaseHelper.cs
index 580e5fc..a546cba 100644
--- a/OptixServe.Infrastructure/Utilites/DatabaseHelper.cs
+++ b/OptixServe.Infrastructure/Utilites/DatabaseHelper.cs
@@ -1,5 +1,6 @@
using Microsoft.EntityFrameworkCore;
using OptixServe.Infrastructure.Configuration;
+using OptixServe.Infrastructure.Data.CompiledModels;
namespace OptixServe.Infrastructure.Utilites;
@@ -22,7 +23,8 @@ public static class DatabaseHelper
var dbPath = dbSettings.Host ?? "optixserve.db";
var connectionString = $"Data Source={dbPath}";
- options.UseSqlite(connectionString, b => b.MigrationsAssembly("OptixServe.Infrastructure"));
+ options.UseSqlite(connectionString, b => b.MigrationsAssembly("OptixServe.Infrastructure"))
+ .UseModel(AppDbContextModel.Instance);
}
else