using Complex.Application; using Complex.Domain.Commons; using Complex.Domain.Entities; using Complex.Infrastructure.Extensions; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Linq.Expressions; using System.Reflection.Emit; using System.Reflection.Metadata; using System.Text; using System.Threading.Tasks; namespace Complex.Infrastructure { public partial class ComplexDBContext : DbContext, IComplexDBContext { public ComplexDBContext() { } public object? Find(Type entityType, object keyId) { return base.Find(entityType, keyId); } public override EntityEntry Add(object entity) { return base.Add(entity); } public ComplexDBContext(DbContextOptions options) : base(options) { } protected override void OnModelCreating(ModelBuilder builder) { foreach (var entityType in builder.Model.GetEntityTypes()) { if (entityType.ClrType.GetCustomAttributes(typeof(AuditableAttribute), true).Length > 0) { builder.Entity(entityType.Name).Property("InsertTime").HasDefaultValue(DateTime.Now); builder.Entity(entityType.Name).Property("UpdateTime"); builder.Entity(entityType.Name).Property("RemoveTime"); builder.Entity(entityType.Name).Property("IsRemoved").HasDefaultValue(false); } } builder.Entity().HasQueryFilter(b => EF.Property(b, "IsRemoved") == false); builder.Entity().HasQueryFilter(b => EF.Property(b, "IsRemoved") == false); builder.Entity().HasQueryFilter(b => EF.Property(b, "IsRemoved") == false); builder.Entity().HasQueryFilter(b => EF.Property(b, "IsRemoved") == false); //builder.ApplyGlobalFilters("IsRemoved", false); // var allEntities = modelBuilder.Model.GetEntityTypes(); //Expression> filterExpr = bm => (bm.GetProperty("IsRemoved").ToString() == "0"); //foreach (var entity in builder.Model.GetEntityTypes()) //{ // //if (!entity.ClrType.IsAssignableTo(typeof(BaseEntity))) // // continue; // if (entity.ClrType.GetCustomAttributes(typeof(AuditableAttribute), true).Length > 0) // entity // //entity.SetQueryFilter(filterExpr); //} } public override int SaveChanges() { var modifiedEntries = ChangeTracker.Entries() .Where(p => p.State == EntityState.Modified || p.State == EntityState.Added || p.State == EntityState.Deleted ); foreach (var item in modifiedEntries) { var entityType = item.Context.Model.FindEntityType(item.Entity.GetType()); if (entityType != null) { if (entityType.ClrType.GetCustomAttributes(typeof(AuditableAttribute), true).Length == 0) continue; var inserted = entityType.FindProperty("InsertTime"); var updated = entityType.FindProperty("UpdateTime"); var RemoveTime = entityType.FindProperty("RemoveTime"); var IsRemoved = entityType.FindProperty("IsRemoved"); if (item.State == EntityState.Added && inserted != null) { item.Property("InsertTime").CurrentValue = DateTime.Now; } if (item.State == EntityState.Modified && updated != null) { item.Property("UpdateTime").CurrentValue = DateTime.Now; } if (item.State == EntityState.Deleted && RemoveTime != null && IsRemoved != null) { item.Property("RemoveTime").CurrentValue = DateTime.Now; item.Property("IsRemoved").CurrentValue = true; item.State = EntityState.Modified; } } } return base.SaveChanges(); } //{ // var entries = ChangeTracker // .Entries() // .Where(e => // e.State == EntityState.Added // || e.State == EntityState.Modified); // foreach (var entityEntry in entries) // { // entityEntry.Property("UpdateTime").CurrentValue = DateTime.Now; // if (entityEntry.State == EntityState.Added) // { // entityEntry.Property("InsertTime").CurrentValue = DateTime.Now; // } // } // entries = ChangeTracker // .Entries() // .Where(e => // e.State == EntityState.Deleted); // foreach (var entityEntry in entries) // { // entityEntry.State = EntityState.Modified; // entityEntry.Property("RemoveTime").CurrentValue = DateTime.Now; // entityEntry.Property("IsRemoved").CurrentValue = true; // } // return base.SaveChanges(); //} public virtual DbSet UnitStates { get; set; } public virtual DbSet Persons { get; set; } public virtual DbSet ComplexPersons { get; set; } public virtual DbSet BasicTables { get; set; } public virtual DbSet Chats { get; set; } public virtual DbSet ComplexEntities { get; set; } public virtual DbSet ComplexManagers { get; set; } public virtual DbSet ComplexUnitEvents { get; set; } public virtual DbSet Posters { get; set; } public virtual DbSet Transactions { get; set; } public virtual DbSet IncomeCostTitles { get; set; } public virtual DbSet TransactionTypes { get; set; } public virtual DbSet Units { get; set; } public virtual DbSet CostCycles { get; set; } public virtual DbSet UnitCosts { get; set; } public virtual DbSet UserTokens { get; set; } public virtual DbSet SmsCodes { get; set; } protected override void ConfigureConventions(ModelConfigurationBuilder builder) { builder.Properties() .HaveConversion() .HaveColumnType("date"); base.ConfigureConventions(builder); } } public class DateOnlyConverter : ValueConverter { public DateOnlyConverter() : base(dateOnly => dateOnly.ToDateTime(TimeOnly.MinValue), dateTime => DateOnly.FromDateTime(dateTime)) { } } }