using AyCode.Core.Consts; using Microsoft.EntityFrameworkCore; using AyCode.Interfaces.TimeStampInfo; using Microsoft.Extensions.Configuration; namespace AyCode.Database.DbContexts; public abstract class AcDbContextBase : DbContext, IAcDbContextBase { private readonly string? _connString; public string Name { get; set; } public Guid SessionId { get; protected set; } = Guid.NewGuid(); protected AcDbContextBase() { _connString = AcEnv.AppConfiguration.GetConnectionString("DeveloperDbConnection"); //DbInterception.Add(new UtcDateTimeDbCommandInterceptor()); } protected AcDbContextBase(string name) : this() { Name = name; } protected AcDbContextBase(DbContextOptions options, string name) : base(options) { Name = name; _connString = AcEnv.AppConfiguration.GetConnectionString("DeveloperDbConnection"); } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseLazyLoadingProxies(true); optionsBuilder.UseSqlServer(_connString); } public override int SaveChanges() { UpdateTimeStampInfoProperties(); return base.SaveChanges(); } public override Task SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken()) { UpdateTimeStampInfoProperties(); return base.SaveChangesAsync(cancellationToken); } public override Task SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = new CancellationToken()) { UpdateTimeStampInfoProperties(); return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken); } private void UpdateTimeStampInfoProperties() { var entries = ChangeTracker.Entries().Where(e => e.Entity is not ITimeStampDisableAutoSet && (e is { State: EntityState.Added, Entity: ITimeStampCreated } || e.State is EntityState.Modified or EntityState.Added && e.Entity is ITimeStampModified)); var utcNow = DateTime.UtcNow; foreach (var entityEntry in entries) { if (entityEntry.Entity is ITimeStampModified timeStampModified) timeStampModified.Modified = utcNow; if (entityEntry.Entity is not ITimeStampCreated timeStampCreated) continue; if (entityEntry.State == EntityState.Added) { timeStampCreated.Created = utcNow; continue; } //entityEntry.State = EntityState.Unchanged; entityEntry.Property(nameof(timeStampCreated.Created)).IsModified = false; } } protected override void OnModelCreating(ModelBuilder modelBuilder) { //modelBuilder.ComplexType(); //modelBuilder.ComplexType(); //modelBuilder.Conventions.Delete(); //modelBuilder.Conventions.Delete(); //modelBuilder.Conventions.Delete(); //modelBuilder.Conventions.Delete(); //var dateTimeConverter = new ValueConverter(v => v, v => DateTime.SpecifyKind(v, DateTimeKind.Utc)); //modelBuilder.UseValueConverterForType(dateTimeConverter); modelBuilder.UseDateTimeUtc(); modelBuilder.EntitiesOfType((type, builder) => { builder.Property(nameof(ITimeStampCreated.Created)).IsRequired(); //.HasDefaultValueSql("getutcdate()"); }); modelBuilder.EntitiesOfType((type, builder) => { builder.Property(nameof(ITimeStampModified.Modified)).IsRequired(); //HasComputedColumnSql("getutcdate()"); }); } public override string ToString() { return $"{GetType().Name}, {Name} - ({SessionId})"; } }