AyCode.Core/AyCode.Database/DbContexts/AcDbContextExtension.cs

127 lines
4.6 KiB
C#

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.DbContexts
{
public static class AcDbContextExtension
{
public static IEntityType? GetEntityType<TEntity>(this DbContext ctx)
{
return ctx.Model.FindEntityType(typeof(TEntity));
}
public static IDictionary<string, object> GetKeysValue<TEntity>(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<IProperty> 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 (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<T>(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<DateTime, DateTime>(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<T>(this ModelBuilder modelBuilder, Action<IMutableEntityType, EntityTypeBuilder> entityTypeBuilder) where T : class
=> modelBuilder.EntitiesOfType(typeof(T), entityTypeBuilder);
public static ModelBuilder EntitiesOfType(this ModelBuilder modelBuilder, Type type, Action<IMutableEntityType, EntityTypeBuilder> entityTypeBuilder)
{
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
if (type.IsAssignableFrom(entityType.ClrType))
entityTypeBuilder(entityType, modelBuilder.Entity(entityType.ClrType));
return modelBuilder;
}
}
}