Files
Finlytic/FinlyticAssets/Database/AssetsDbContext.cs
T

112 lines
4.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using FinlyticAssets.Entities;
using FinlyticCore.Database;
using FinlyticCore.Entities.Settings;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.Design;
namespace FinlyticAssets.Database;
public class AssetsDbContext : DbContext, ISettingsDbContext
{
public AssetsDbContext(DbContextOptions<AssetsDbContext> options) : base(options)
{
}
public DbSet<SettingEntity> DynamicSettings => Set<SettingEntity>();
public DbSet<Settings> Settings { get; set; }
public DbSet<AssetEntity> TradeRepublicAssets { get; set; }
public DbSet<TagEntity> TradeRepublicTags { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<SettingEntity>(entity =>
{
entity.HasKey(e => e.Id);
entity.HasIndex(e => e.Key).IsUnique();
});
modelBuilder.Entity<AssetEntity>(entity =>
{
entity.HasKey(e => new {e.Isin, e.InstrumentCategory});
entity.HasIndex(e => e.LastUpdatedAt);
entity.HasDiscriminator<string>("AssetType")
.HasValue<StockEntity>("Stock")
.HasValue<CryptoEntity>("Crypto")
.HasValue<EtfEntity>("Etf")
.HasValue<SyntheticEntity>("Synthetic")
.HasValue<BondEntity>("Bond")
.HasValue<DerivativeEntity>("Derivative");
});
var stringListConverter =
new Microsoft.EntityFrameworkCore.Storage.ValueConversion.ValueConverter<List<string>, string>(
v => System.Text.Json.JsonSerializer.Serialize(v, (System.Text.Json.JsonSerializerOptions?)null),
v => System.Text.Json.JsonSerializer.Deserialize<List<string>>(v,
(System.Text.Json.JsonSerializerOptions?)null) ?? new List<string>()
);
var stringListComparer = new ValueComparer<List<string>>(
(c1, c2) => c1 != null && c2 != null ? c1.SequenceEqual(c2) : c1 == c2,
c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v.GetHashCode())),
c => c.ToList()
);
modelBuilder.Entity<StockEntity>()
.Property(e => e.DerivativeProductCategories)
.HasConversion(stringListConverter, stringListComparer);
modelBuilder.Entity<SyntheticEntity>()
.Property(e => e.DerivativeProductCategories)
.HasConversion(stringListConverter, stringListComparer);
modelBuilder.Entity<DerivativeEntity>()
.Property(e => e.DerivativeProductCategories)
.HasConversion(stringListConverter, stringListComparer);
modelBuilder.Entity<EtfEntity>()
.Property(e => e.DerivativeProductCategories)
.HasConversion(stringListConverter, stringListComparer);
modelBuilder.Entity<TagEntity>(entity => { entity.HasKey(e => e.Id); });
modelBuilder.Entity<Settings>(entity =>
{
entity.HasKey(e => e.Id);
entity.Property(e => e.CurrentScanningType)
.HasConversion<string>()
.HasMaxLength(50);
});
modelBuilder.Entity<AssetEntity>()
.HasMany(a => a.Tags)
.WithMany(t => t.Assets);
}
protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
{
base.ConfigureConventions(configurationBuilder);
configurationBuilder.Properties<DateTime>()
.HaveConversion(typeof(FinlyticCore.Converters.UtcDateTimeConverter));
configurationBuilder.Properties<DateTime?>()
.HaveConversion(typeof(FinlyticCore.Converters.NullableUtcDateTimeConverter));
}
}
public class AssetsDbContextFactory : IDesignTimeDbContextFactory<AssetsDbContext>
{
public AssetsDbContext CreateDbContext(string[] args)
{
var optionsBuilder = new DbContextOptionsBuilder<AssetsDbContext>();
optionsBuilder.UseNpgsql("Host=localhost;Database=assets;Username=postgres;Password=postgres");
return new AssetsDbContext(optionsBuilder.Options);
}
}