AyCode.Core/AyCode.Database/DbContexts/AcDbContextBase.cs

118 lines
3.9 KiB
C#

using AyCode.Core.Consts;
using Microsoft.EntityFrameworkCore;
using AyCode.Interfaces.TimeStampInfo;
using Microsoft.Extensions.Configuration;
namespace AyCode.Database.DbContexts;
public abstract class AcDbContextBase : DbContext
{
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<DbContext> 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<int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken())
{
UpdateTimeStampInfoProperties();
return base.SaveChangesAsync(cancellationToken);
}
public override Task<int> 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)
{
//entityEntry.DebugView.LongView
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.Property(nameof(timeStampCreated.Created)).IsModified = false;
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//modelBuilder.ComplexType<IPAddress>();
//modelBuilder.ComplexType<PhysicalAddress>();
//modelBuilder.Conventions.Delete<PluralizingTableNameConvention>();
//modelBuilder.Conventions.Delete<OneToManyCascadeDeleteConvention>();
//modelBuilder.Conventions.Delete<ManyToManyCascadeDeleteConvention>();
//modelBuilder.Conventions.Delete<OneToOneConstraintIntroductionConvention>();
//var dateTimeConverter = new ValueConverter<DateTime, DateTime>(v => v, v => DateTime.SpecifyKind(v, DateTimeKind.Utc));
//modelBuilder.UseValueConverterForType<DateTime>(dateTimeConverter);
modelBuilder.UseDateTimeUtc();
modelBuilder.EntitiesOfType<ITimeStampCreated>((type, builder) =>
{
builder.Property<DateTime>(nameof(ITimeStampCreated.Created)).IsRequired(); //.HasDefaultValueSql("getutcdate()");
});
modelBuilder.EntitiesOfType<ITimeStampModified>((type, builder) =>
{
builder.Property<DateTime>(nameof(ITimeStampModified.Modified)).IsRequired(); //HasComputedColumnSql("getutcdate()");
});
}
public override string ToString()
{
return $"{GetType().Name}, {Name} - ({SessionId})";
}
}