159 lines
6.5 KiB
C#

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using gehGassiApp.Domain.Common;
using gehGassiApp.Data.Converter;
using gehGassiApp.Domain.Dogs;
using gehGassiApp.Domain.Favourites;
using gehGassiApp.Domain.Messages;
using gehGassiApp.Domain.News;
using gehGassiApp.Domain.Payment;
using gehGassiApp.Domain.Users;
using gehGassiApp.Domain.Walkers;
using gehGassiApp.Domain.Walks;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace gehGassiApp.Data
{
/// <summary>
/// Repräsentiert den lokalen Datenbank Kontext
/// </summary>
public class LocalDbContext : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<AppUser> AppUsers { get; set; }
public DbSet<DogWalkerProfile> DogWalkerProfiles { get; set; }
public DbSet<SyncInfoPull> SyncInfosPull { get; set; }
public DbSet<SyncInfoPush> SyncInfosPush { get; set; }
public DbSet<NewsCategory> NewsCategories { get; set; }
public DbSet<Conversation> Conversations { get; set; }
public DbSet<Message> Messages { get; set; }
public DbSet<DogRace> DogRaces { get; set; }
public DbSet<Dog> Dogs { get; set; }
public DbSet<PublicWalkRequest> PublicWalkRequests { get; set; }
public DbSet<PublicWalkResponse> PublicWalkResponses { get; set; }
public DbSet<Walk> Walks { get; set; }
public DbSet<WalkingTime> WalkingTimes { get; set; }
public DbSet<Rating> Ratings { get; set; }
public DbSet<Favourite> Favourites { get; set; }
public DbSet<SystemMessage> SystemMessages { get; set; }
public DbSet<TransactionFee> TransactionFees { get; set; }
public DbSet<Payout> Payouts { get; set; }
//Views
public DbSet<PublicWalkRequestWithNames> PublicWalkRequestsWithNames { get; set; }
private readonly string _databasePath; //Für Migrations in der Packagemanager console eingefügt
/// <summary>
/// Erstellt eine Instanz
/// </summary>
/// <param name="databasePath">Pfad zur Datenbank</param>
public LocalDbContext(string databasePath) //Für Migrations in der Packagemanager console eingefügt
{
_databasePath = databasePath;
Database.Migrate();
}
/// <summary>
/// Erstellt eine Instanz
/// </summary>
/// <param name="options">Datenbank Optionen</param>
public LocalDbContext(DbContextOptions options) : base(options)
{
}
/// <inheritdoc />
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
if (!string.IsNullOrWhiteSpace(_databasePath)) //Für Migrations in der Packagemanager console eingefügt
{
optionsBuilder.UseSqlite($"Filename={_databasePath}");
}
}
/// <inheritdoc />
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
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 DateTimeOffsetToUtcDateTimeTicksConverter());
}
properties = entityType.ClrType.GetProperties().Where(p => p.PropertyType == typeof(TimeSpan));
foreach (var property in properties)
{
modelBuilder
.Entity(entityType.Name)
.Property(property.Name)
.HasConversion(new TimeSpanToTicksConverter());
}
}
}
modelBuilder.Entity<AppUser>().OwnsOne(p => p.Address);
modelBuilder.Entity<AppUser>().OwnsOne(p => p.Contact);
modelBuilder.Entity<AppUser>().OwnsOne(p => p.SocialMedia);
modelBuilder.Entity<AppUser>().OwnsOne(p => p.RatingStatistics);
modelBuilder.Entity<AppUser>().OwnsOne(p => p.RatingStatisticsWalker);
modelBuilder.Entity<Message>().HasOne<Conversation>().WithMany().HasForeignKey(c => c.ConversationId).OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<Dog>().OwnsOne(p => p.RatingStatistics);
modelBuilder.Entity<Dog>().HasOne<DogRace>().WithMany().HasForeignKey(c => c.DogRaceId).OnDelete(DeleteBehavior.ClientSetNull);
modelBuilder.Entity<PublicWalkRequest>().OwnsOne(p => p.PickupAddress);
modelBuilder.Entity<Walk>().OwnsOne(p => p.PickupAddress);
modelBuilder.Entity<Walk>().OwnsOne(p => p.ReturnAddress);
//Views
modelBuilder.Entity<PublicWalkRequestWithNames>().HasNoKey().ToView("vw_PublicWalkRequestWithNames");
}
}
//Für Migrations in der Packagemanager console eingefügt
public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<LocalDbContext>
{
public LocalDbContext CreateDbContext(string[] args)
{
Debug.WriteLine(Directory.GetCurrentDirectory() + @"\Config.db");
return new LocalDbContext(Directory.GetCurrentDirectory() + @"\Config.db");
}
}
}