diff --git a/DataStore/DatabaseService.cs b/DataStore/DatabaseService.cs
new file mode 100644
index 0000000..06e6f42
--- /dev/null
+++ b/DataStore/DatabaseService.cs
@@ -0,0 +1,166 @@
+using System;
+using System.Threading.Tasks;
+using Microsoft.EntityFrameworkCore;
+
+namespace Logof_Client;
+
+///
+/// Zentrale Datenbankverwaltung für Logof Client.
+///
+/// Zuständig für:
+/// - PostgreSQL-Verbindung
+/// - EF Core DbContext
+/// - Datenbankmodelle
+/// - Migrationen
+/// - Verbindungstest
+///
+public static class DatabseService
+{
+ private static DbContextOptions? _options;
+
+ ///
+ /// Initialisiert die Datenbankverbindung.
+ /// Sollte einmal beim Programmstart aufgerufen werden.
+ ///
+ public static void Initialize(string connectionString)
+ {
+ if (string.IsNullOrWhiteSpace(connectionString))
+ throw new ArgumentException(
+ "Kein Datenbank-Connection-String angegeben.",
+ nameof(connectionString));
+
+ var builder = new DbContextOptionsBuilder();
+
+ builder.UseNpgsql(connectionString);
+
+ _options = builder.Options;
+ }
+
+ ///
+ /// Erstellt einen neuen DbContext.
+ ///
+ public static LogofDbContext GetContext()
+ {
+ if (_options == null)
+ throw new InvalidOperationException(
+ "DB wurde noch nicht initialisiert. " +
+ "Rufen Sie DB.Initialize(...) auf.");
+
+ return new LogofDbContext(_options);
+ }
+
+ ///
+ /// Testet die Verbindung zum Datenbankserver.
+ ///
+ public static async Task TestConnectionAsync()
+ {
+ try
+ {
+ await using var db = GetContext();
+ return await db.Database.CanConnectAsync();
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ ///
+ /// Erstellt bzw. aktualisiert das Datenbankschema
+ /// anhand der vorhandenen EF-Core-Migrationen.
+ ///
+ public static async Task MigrateAsync()
+ {
+ await using var db = GetContext();
+
+ await db.Database.MigrateAsync();
+ }
+}
+
+
+// ============================================================================
+// DATABASE CONTEXT
+// ============================================================================
+
+public class LogofDbContext : DbContext
+{
+ public DbSet Customers => Set();
+
+ public LogofDbContext(
+ DbContextOptions options)
+ : base(options)
+ {
+ }
+
+ protected override void OnModelCreating(ModelBuilder modelBuilder)
+ {
+ base.OnModelCreating(modelBuilder);
+
+ // --------------------------------------------------------------------
+ // Customer
+ // --------------------------------------------------------------------
+
+ modelBuilder.Entity(entity =>
+ {
+ entity.ToTable("customers");
+
+ entity.HasKey(x => x.Id);
+
+ entity.Property(x => x.Id)
+ .ValueGeneratedOnAdd();
+
+ entity.Property(x => x.Name)
+ .HasMaxLength(255)
+ .IsRequired();
+
+ entity.Property(x => x.Description)
+ .HasMaxLength(4000);
+
+ entity.Property(x => x.SenderAddress)
+ .HasMaxLength(4000);
+
+ entity.Property(x => x.Separator)
+ .HasMaxLength(1)
+ .IsRequired();
+
+ // Optimistic Concurrency
+ entity.Property(x => x.Version)
+ .IsConcurrencyToken();
+
+ entity.Property(x => x.CreatedAt)
+ .IsRequired();
+
+ entity.Property(x => x.UpdatedAt)
+ .IsRequired();
+ });
+ }
+}
+
+
+// ============================================================================
+// DATABASE MODELS
+// ============================================================================
+
+public class CustomerEx
+{
+ public long Id { get; set; }
+
+ public string Name { get; set; } = "";
+
+ public string Description { get; set; } = "";
+
+ public string SenderAddress { get; set; } = "";
+
+ public char Separator { get; set; } = ',';
+
+ ///
+ /// Wird bei jeder Änderung erhöht.
+ /// Verhindert, dass zwei Benutzer sich gegenseitig
+ /// Änderungen überschreiben.
+ ///
+ public long Version { get; set; } = 1;
+
+ public DateTime CreatedAt { get; set; }
+
+ public DateTime UpdatedAt { get; set; }
+}
\ No newline at end of file