76 lines
2.7 KiB
C#
76 lines
2.7 KiB
C#
using FinlyticCore.Database;
|
|
using FinlyticCore.Entities.Settings;
|
|
using FinlyticSentiment.Entities;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.EntityFrameworkCore.Design;
|
|
|
|
namespace FinlyticSentiment.Database;
|
|
|
|
/// <summary>
|
|
/// EF Core DbContext for managing FinlyticSentiment persistent entities and dynamic settings.
|
|
/// </summary>
|
|
public class SentimentDbContext : DbContext, ISettingsDbContext
|
|
{
|
|
public SentimentDbContext(DbContextOptions<SentimentDbContext> options) : base(options)
|
|
{
|
|
}
|
|
|
|
public DbSet<SettingEntity> DynamicSettings => Set<SettingEntity>();
|
|
public DbSet<ArticleSentimentEntity> ArticleSentiments => Set<ArticleSentimentEntity>();
|
|
public DbSet<CompanySentimentSummaryEntity> CompanySentiments => Set<CompanySentimentSummaryEntity>();
|
|
public DbSet<SectorSentimentSummaryEntity> SectorSentiments => Set<SectorSentimentSummaryEntity>();
|
|
|
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
|
{
|
|
base.OnModelCreating(modelBuilder);
|
|
|
|
// Dynamic Settings
|
|
modelBuilder.Entity<SettingEntity>(entity =>
|
|
{
|
|
entity.HasKey(e => e.Id);
|
|
entity.HasIndex(e => e.Key).IsUnique();
|
|
});
|
|
|
|
// Individual Article Sentiments
|
|
modelBuilder.Entity<ArticleSentimentEntity>(entity =>
|
|
{
|
|
entity.HasKey(e => e.Id);
|
|
|
|
// Prevent duplicate analysis of the same article for the same asset
|
|
entity.HasIndex(e => new { e.ArticleId, e.Isin }).IsUnique();
|
|
|
|
// High-performance time-series index for timeline charts & time-decay scans
|
|
entity.HasIndex(e => new { e.Isin, e.PublishedAtUtc });
|
|
|
|
entity.HasIndex(e => e.AnalyzedAtUtc);
|
|
entity.HasIndex(e => e.Sector);
|
|
});
|
|
|
|
// Pre-Aggregated Company Sentiment Summaries
|
|
modelBuilder.Entity<CompanySentimentSummaryEntity>(entity =>
|
|
{
|
|
entity.HasKey(e => e.Isin);
|
|
entity.HasIndex(e => e.Sector);
|
|
entity.HasIndex(e => e.WeightedScore);
|
|
entity.HasIndex(e => e.LastUpdatedUtc);
|
|
});
|
|
|
|
// Pre-Aggregated Sector Sentiment Summaries
|
|
modelBuilder.Entity<SectorSentimentSummaryEntity>(entity =>
|
|
{
|
|
entity.HasKey(e => e.Sector);
|
|
entity.HasIndex(e => e.LastUpdatedUtc);
|
|
});
|
|
}
|
|
}
|
|
|
|
public class SentimentDbContextFactory : IDesignTimeDbContextFactory<SentimentDbContext>
|
|
{
|
|
public SentimentDbContext CreateDbContext(string[] args)
|
|
{
|
|
var optionsBuilder = new DbContextOptionsBuilder<SentimentDbContext>();
|
|
optionsBuilder.UseNpgsql("Host=localhost;Database=sentiment;Username=postgres;Password=postgres");
|
|
return new SentimentDbContext(optionsBuilder.Options);
|
|
}
|
|
}
|