Files
BimAI/Bimix.Infrastructure/Data/BimixDbContext.cs

90 lines
3.4 KiB
C#

using Bimix.Domain.Entities;
using Microsoft.EntityFrameworkCore;
namespace Bimix.Infrastructure.Data;
public class BimixDbContext(DbContextOptions<BimixDbContext> options) : DbContext(options)
{
public DbSet<Product> Products { get; set; }
public DbSet<SyncState> SyncStates { get; set; }
public DbSet<User> Users { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// Product properties
modelBuilder.Entity<Product>().HasKey(x => x.Id);
modelBuilder.Entity<Product>().Property(x => x.Name).IsRequired().HasMaxLength(512);
modelBuilder.Entity<Product>().Property(x => x.Code).IsRequired().HasMaxLength(40);
modelBuilder.Entity<Product>().Property(x => x.Ean).IsRequired().HasMaxLength(50);
modelBuilder.Entity<Product>().Property(x => x.StockAddresses).IsRequired().HasMaxLength(512);
// SyncState properties
modelBuilder.Entity<SyncState>().HasKey((x => x.Entity));
// User properties
modelBuilder.Entity<User>().HasKey(x => x.Id);
modelBuilder.Entity<User>().Property(x => x.GoogleId).IsRequired().HasMaxLength(100);
modelBuilder.Entity<User>().Property(x => x.Email).IsRequired().HasMaxLength(255);
modelBuilder.Entity<User>().Property(x => x.FullName).IsRequired().HasMaxLength(255);
modelBuilder.Entity<User>().Property(x => x.IsActive).IsRequired().HasDefaultValue(false);
modelBuilder.Entity<User>().Property(x => x.LastLoginAt).IsRequired(false);
// User indexes
modelBuilder.Entity<User>().HasIndex(x => x.GoogleId).IsUnique().HasDatabaseName("IX_Users_GoogleId");
modelBuilder.Entity<User>().HasIndex(x => x.Email).IsUnique().HasDatabaseName("IX_Users_Email");
// Configure defaults for all CreatedAt and UpdatedAt in entities
ConfigureBaseEntity(modelBuilder);
}
private void ConfigureBaseEntity(ModelBuilder modelBuilder)
{
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
if (typeof(BaseEntity).IsAssignableFrom(entityType.ClrType))
{
modelBuilder.Entity(entityType.ClrType)
.Property(nameof(BaseEntity.CreatedAt))
.HasDefaultValueSql("GETUTCDATE()");
modelBuilder.Entity(entityType.ClrType)
.Property(nameof(BaseEntity.UpdatedAt))
.HasDefaultValueSql("GETUTCDATE()");
}
}
}
public override int SaveChanges()
{
UpdateTimestamps();
return base.SaveChanges();
}
public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
{
UpdateTimestamps();
return base.SaveChangesAsync(cancellationToken);
}
private void UpdateTimestamps()
{
var entities = ChangeTracker.Entries<BaseEntity>();
foreach (var entity in entities)
{
if (entity.State == EntityState.Added)
{
entity.Entity.CreatedAt = DateTime.UtcNow;
entity.Entity.UpdatedAt = DateTime.UtcNow;
break;
}
else if (entity.State == EntityState.Modified)
{
entity.Entity.UpdatedAt = DateTime.UtcNow;
break;
}
}
}
}