You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
4.0 KiB
104 lines
4.0 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel.DataAnnotations;
|
|
using System.Linq;
|
|
using Infrastructure.Domain;
|
|
using Infrastructure.Extensions;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace Infrastructure.Data
|
|
{
|
|
public class EfDbContext : DbContext
|
|
{
|
|
private readonly IHttpContextAccessor _httpContext;
|
|
|
|
public EfDbContext(DbContextOptions options, IHttpContextAccessor httpContext) : base(options)
|
|
{
|
|
this._httpContext = httpContext;
|
|
}
|
|
|
|
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
|
{
|
|
optionsBuilder.EnableSensitiveDataLogging();
|
|
base.OnConfiguring(optionsBuilder);
|
|
}
|
|
|
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
|
{
|
|
base.OnModelCreating(modelBuilder);
|
|
modelBuilder.RemovePluralizingTableNameConvention();
|
|
OnModelCreatingAction(modelBuilder);
|
|
foreach (var entity in modelBuilder.Model.GetEntityTypes())
|
|
{
|
|
if (entity.GetProperties().Any(o => o.Name == "Id"))
|
|
{
|
|
modelBuilder.Entity(entity.Name).HasKey("Id");
|
|
}
|
|
if (entity.GetProperties().Any(o => o.Name == "RowVersion"))
|
|
{
|
|
modelBuilder.Entity(entity.Name).Property("RowVersion")?.IsConcurrencyToken().ValueGeneratedNever();
|
|
}
|
|
}
|
|
}
|
|
|
|
public override int SaveChanges()
|
|
{
|
|
this.ChangeTracker.DetectChanges();
|
|
var entries = this.ChangeTracker.Entries().Where(o => o.State == EntityState.Added ||
|
|
o.State == EntityState.Modified || o.State == EntityState.Deleted).ToList();
|
|
foreach (var entry in entries)
|
|
{
|
|
var entity = entry.Entity as BaseEntity;
|
|
if (entity is IValidatableObject)
|
|
{
|
|
var validationResults = new List<ValidationResult>();
|
|
if (!Validator.TryValidateObject(entry.Entity, new ValidationContext(entity, null, null), validationResults, true))
|
|
{
|
|
throw new EntityInvalidException(validationResults, $"{entity.GetType().FullName} valid error");
|
|
}
|
|
}
|
|
var now = DateTimeOffset.Now;
|
|
var rowVersion = Guid.NewGuid().ToString();
|
|
var userName = this._httpContext?.HttpContext?.User?.Identity?.Name ?? "admin";
|
|
if (entity is Entity)
|
|
{
|
|
(entity as Entity).RowVersion = rowVersion;
|
|
}
|
|
if (entry.State == EntityState.Added)
|
|
{
|
|
entity.UpdatedOn = now;
|
|
}
|
|
else if (entry.State == EntityState.Modified)
|
|
{
|
|
if (entity is IDisableUpdate || entity.IsReadOnly)
|
|
{
|
|
throw new Exception("this entity is readonly or disable update");
|
|
}
|
|
entity.UpdatedOn = now;
|
|
}
|
|
else if (entry.State == EntityState.Deleted || entity.IsReadOnly)
|
|
{
|
|
if (entity is IDisableDelete || entity.IsReadOnly)
|
|
{
|
|
throw new Exception("this entity can't delete");
|
|
}
|
|
}
|
|
Console.WriteLine($"{entity.GetType().Name}:{entry.State.ToString()}:{entry.OriginalValues.ToObject().ToJson()}/{entry.CurrentValues.ToObject().ToJson()}");
|
|
}
|
|
try
|
|
{
|
|
return base.SaveChanges();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ex.PrintStack();
|
|
var list = entries.Select(o => o.Entity).ToList();
|
|
Console.WriteLine(list.ToJson());
|
|
throw new Exception(ex.Message, ex);
|
|
}
|
|
}
|
|
|
|
public static Action<ModelBuilder> OnModelCreatingAction;
|
|
}
|
|
} |