XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

EARSystem

【ASP】耳间,网页端的情绪智能推荐系统

公开
关注 0 Fork 0 Star 0
UTF-8
using EARSystem.Core;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;

namespace EARSystem.Infrastructure;

public class ApplicationUser : IdentityUser
{
    public string DisplayName { get; set; } = "";
    public bool IsDemo { get; set; }
}

public class AppDbContext(DbContextOptions<AppDbContext> options) : IdentityDbContext<ApplicationUser>(options)
{
    public DbSet<MoodEntry> Moods => Set<MoodEntry>();
    public DbSet<UserPreference> Preferences => Set<UserPreference>();
    public DbSet<Place> Places => Set<Place>();
    public DbSet<PlaceAtmosphere> Atmospheres => Set<PlaceAtmosphere>();
    public DbSet<Experience> Experiences => Set<Experience>();
    public DbSet<Favorite> Favorites => Set<Favorite>();
    public DbSet<RecommendationRecord> Recommendations => Set<RecommendationRecord>();
    public DbSet<RuleConfiguration> Rules => Set<RuleConfiguration>();

    protected override void OnModelCreating(ModelBuilder model)
    {
        base.OnModelCreating(model);
        model.Entity<ApplicationUser>().Property(x => x.DisplayName).HasMaxLength(40);
        model.Entity<MoodEntry>(b => {
            b.HasIndex(x => new { x.UserId, x.RecordedAt });
            b.Property(x => x.Thoughts).HasMaxLength(5000);
            b.Property(x => x.TagsJson).HasMaxLength(1000);
            b.Property(x => x.Version).IsConcurrencyToken();
            b.HasOne<ApplicationUser>().WithMany().HasForeignKey(x => x.UserId).OnDelete(DeleteBehavior.Cascade);
        });
        model.Entity<UserPreference>(b => {
            b.HasKey(x => x.UserId);
            b.Property(x => x.Budget).HasPrecision(10, 2);
            b.HasOne<ApplicationUser>().WithOne().HasForeignKey<UserPreference>(x => x.UserId).OnDelete(DeleteBehavior.Cascade);
        });
        model.Entity<Place>(b => {
            b.Property(x => x.Name).HasMaxLength(100);
            b.Property(x => x.Address).HasMaxLength(300);
            b.Property(x => x.Description).HasMaxLength(1000);
            b.Property(x => x.AuthorizedExternalId).HasMaxLength(100);
            b.Property(x => x.Price).HasPrecision(10, 2);
            b.HasIndex(x => new { x.Source, x.Category });
            b.HasOne(x => x.Atmosphere).WithOne().HasForeignKey<PlaceAtmosphere>(x => x.PlaceId).OnDelete(DeleteBehavior.Cascade);
        });
        model.Entity<PlaceAtmosphere>().HasKey(x => x.PlaceId);
        model.Entity<PlaceAtmosphere>().Property(x => x.Evidence).HasMaxLength(500);
        model.Entity<Experience>(b => {
            b.HasIndex(x => new { x.UserId, x.PlaceId, x.VisitDay }).IsUnique();
            b.HasIndex(x => new { x.UserId, x.VisitedAt });
            b.HasIndex(x => new { x.PlaceId, x.Contribute });
            b.Property(x => x.Thoughts).HasMaxLength(5000);
            b.Property(x => x.Version).IsConcurrencyToken();
            b.HasOne(x => x.Place).WithMany().HasForeignKey(x => x.PlaceId).OnDelete(DeleteBehavior.Restrict);
            b.HasOne<ApplicationUser>().WithMany().HasForeignKey(x => x.UserId).OnDelete(DeleteBehavior.Cascade);
        });
        model.Entity<Favorite>(b => {
            b.HasKey(x => new { x.UserId, x.PlaceId });
            b.HasOne(x => x.Place).WithMany().HasForeignKey(x => x.PlaceId).OnDelete(DeleteBehavior.Restrict);
            b.HasOne<ApplicationUser>().WithMany().HasForeignKey(x => x.UserId).OnDelete(DeleteBehavior.Cascade);
        });
        model.Entity<RecommendationRecord>(b => {
            b.HasIndex(x => new { x.UserId, x.CreatedAt });
            b.Property(x => x.AlgorithmVersion).HasMaxLength(50);
            b.HasOne<ApplicationUser>().WithMany().HasForeignKey(x => x.UserId).OnDelete(DeleteBehavior.Cascade);
        });
        model.Entity<RuleConfiguration>(b => {
            b.Property(x => x.Version).HasMaxLength(50);
            b.Property(x => x.ConcurrencyStamp).IsConcurrencyToken();
        });
        // UTC ticks preserve ordering on both SQL Server and the isolated SQLite test database.
        foreach (var type in model.Model.GetEntityTypes())
        foreach (var property in type.GetProperties().Where(p => p.ClrType == typeof(DateTimeOffset)))
            property.SetValueConverter(new Microsoft.EntityFrameworkCore.Storage.ValueConversion.ValueConverter<DateTimeOffset, long>(
                value => value.UtcTicks, ticks => new DateTimeOffset(ticks, TimeSpan.Zero)));
    }
}

public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<AppDbContext>
{
    public AppDbContext CreateDbContext(string[] args)
    {
        var connection = Environment.GetEnvironmentVariable("ConnectionStrings__DefaultConnection")
            ?? "Server=(localdb)\\MSSQLLocalDB;Database=EARSystem;Trusted_Connection=True;TrustServerCertificate=True";
        return new(new DbContextOptionsBuilder<AppDbContext>().UseSqlServer(connection).Options);
    }
}