using System; using System.Collections.Generic; using System.Linq; using System.Reflection.Emit; using System.Security.Principal; using System.Text; using System.Threading.Tasks; using AyCode.Interfaces.Entities; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; namespace AyCode.Database.Extensions { public static class AcDbContextExtension { public static IEntityType? GetEntityType(this DbContext ctx) { return ctx.Model.FindEntityType(typeof(TEntity)); } public static IDictionary GetKeysValue(this DbContext ctx, TEntity entity) where TEntity : class, IEntity { if (ctx == null) throw new ArgumentNullException(nameof(ctx)); if (entity == null) throw new ArgumentNullException(nameof(entity)); var entry = ctx.Entry(entity); var primaryKey = entry.Metadata.FindPrimaryKey(); var keys = primaryKey.Properties.ToDictionary(x => x.Name, x => x.PropertyInfo.GetValue(entity)); return keys; } public static IEnumerable GetModifiedProperties(this DbContext ctx, object entity) { if (ctx == null) throw new ArgumentNullException(nameof(ctx)); if (entity == null) throw new ArgumentNullException(nameof(entity)); var entry = ctx.Entry(entity); var originalValues = entry.OriginalValues; var currentValues = entry.CurrentValues; foreach (var prop in originalValues.Properties) { if (object.Equals(originalValues[prop.Name], currentValues[prop.Name]) == false) { yield return prop; } } } public static void ResetValues(this DbContext ctx, object entity) { if (ctx == null) throw new ArgumentNullException(nameof(ctx)); if (entity == null) throw new ArgumentNullException(nameof(entity)); var entry = ctx.Entry(entity); var originalValues = entry.OriginalValues; var currentValues = entry.CurrentValues; foreach (var prop in originalValues.Properties) { currentValues[prop.Name] = originalValues[prop.Name]; } entry.State = EntityState.Unchanged; } public static ModelBuilder UseValueConverterForType(this ModelBuilder modelBuilder, ValueConverter converter) { return modelBuilder.UseValueConverterForType(typeof(T), converter); } public static ModelBuilder UseValueConverterForType(this ModelBuilder modelBuilder, Type type, ValueConverter converter) { foreach (var entityType in modelBuilder.Model.GetEntityTypes()) { foreach (var property in entityType.ClrType.GetProperties()) { if (property.PropertyType == type) modelBuilder.Entity(entityType.Name).Property(property.Name).HasConversion(converter); } } return modelBuilder; } public static void UseDateTimeUtc(this ModelBuilder modelBuilder) { var dateTimeConverter = new ValueConverter(v => v, v => DateTime.SpecifyKind(v, DateTimeKind.Utc)); foreach (var entityType in modelBuilder.Model.GetEntityTypes()) { foreach (var property in entityType.GetProperties()) { if (property.ClrType == typeof(DateTime) || property.ClrType == typeof(DateTime?)) property.SetValueConverter(dateTimeConverter); } } } public static ModelBuilder EntitiesOfType(this ModelBuilder modelBuilder, Action entityTypeBuilder) where T : class => modelBuilder.EntitiesOfType(typeof(T), entityTypeBuilder); public static ModelBuilder EntitiesOfType(this ModelBuilder modelBuilder, Type type, Action entityTypeBuilder) { foreach (var entityType in modelBuilder.Model.GetEntityTypes()) if (type.IsAssignableFrom(entityType.ClrType)) entityTypeBuilder(entityType, modelBuilder.Entity(entityType.ClrType)); return modelBuilder; } } }