249 lines
8.5 KiB
C#
249 lines
8.5 KiB
C#
using Microsoft.EntityFrameworkCore;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
|
|
namespace IRaCIS.Core.Infra.EFCore;
|
|
|
|
public static class DbContextExt
|
|
{
|
|
|
|
/// <summary>
|
|
/// 获取变化的实体信息
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="db"></param>
|
|
/// <returns></returns>
|
|
public static IEnumerable<ChangeEntry> GetChanges<T>(this DbContext db)
|
|
{
|
|
return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Modified && e.Entity is T).Select(e =>
|
|
{
|
|
var originalObject = e.OriginalValues.ToObject();
|
|
var currentObject = e.CurrentValues.ToObject();
|
|
return new ChangeEntry
|
|
{
|
|
EntityState = e.State,
|
|
Entity = e.Entity,
|
|
EntityType = e.OriginalValues.EntityType.ClrType,
|
|
ChangeProperties = e.OriginalValues.Properties.Select(p => (Property: p, Value: p.PropertyInfo.GetValue(originalObject))).Zip(e.CurrentValues.Properties.Select(p => (Property: p, Value: p.PropertyInfo.GetValue(currentObject))), (t1, t2) => new ChangePropertyInfo()
|
|
{
|
|
PropertyInfo = t1.Property.PropertyInfo,
|
|
OriginalValue = t1.Value,
|
|
CurrentValue = t2.Value,
|
|
IsPrimaryKey = t1.Property.IsPrimaryKey(),
|
|
IsForeignKey = t1.Property.IsForeignKey()
|
|
}).Where(t => Comparer.Default.Compare(t.OriginalValue, t.CurrentValue) != 0).ToList()
|
|
};
|
|
});
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// 获取变化的实体信息
|
|
/// </summary>
|
|
/// <param name="db"></param>
|
|
/// <returns></returns>
|
|
public static IEnumerable<ChangeEntry> GetChanges(this DbContext db)
|
|
{
|
|
return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Modified).Select(e =>
|
|
{
|
|
var originalObject = e.OriginalValues.ToObject();
|
|
var currentObject = e.CurrentValues.ToObject();
|
|
return new ChangeEntry()
|
|
{
|
|
EntityState = e.State,
|
|
Entity = e.Entity,
|
|
EntityType = e.OriginalValues.EntityType.ClrType,
|
|
ChangeProperties = e.OriginalValues.Properties.Select(p => (Property: p, Value: p.PropertyInfo.GetValue(originalObject))).Zip(e.CurrentValues.Properties.Select(p => (Property: p, Value: p.PropertyInfo.GetValue(currentObject))), (t1, t2) => new ChangePropertyInfo()
|
|
{
|
|
PropertyInfo = t1.Property.PropertyInfo,
|
|
OriginalValue = t1.Value,
|
|
CurrentValue = t2.Value,
|
|
IsPrimaryKey = t1.Property.IsPrimaryKey(),
|
|
IsForeignKey = t1.Property.IsForeignKey(),
|
|
}).Where(t => Comparer.Default.Compare(t.OriginalValue, t.CurrentValue) != 0).ToList()
|
|
};
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取添加的实体信息
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="db"></param>
|
|
/// <returns></returns>
|
|
public static IEnumerable<ChangeEntry> GetAdded<T>(this DbContext db)
|
|
{
|
|
return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Added && e.Entity is T).Select(e =>
|
|
{
|
|
var currentObject = e.CurrentValues.ToObject();
|
|
return new ChangeEntry
|
|
{
|
|
EntityState = e.State,
|
|
Entity = e.Entity,
|
|
EntityType = e.CurrentValues.EntityType.ClrType,
|
|
ChangeProperties = e.CurrentValues.Properties.Select(p => new ChangePropertyInfo()
|
|
{
|
|
PropertyInfo = p.PropertyInfo,
|
|
CurrentValue = p.PropertyInfo.GetValue(currentObject),
|
|
IsPrimaryKey = p.IsPrimaryKey(),
|
|
IsForeignKey = p.IsForeignKey(),
|
|
}).ToList()
|
|
};
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取添加的实体信息
|
|
/// </summary>
|
|
/// <param name="db"></param>
|
|
/// <returns></returns>
|
|
public static IEnumerable<ChangeEntry> GetAdded(this DbContext db)
|
|
{
|
|
return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Added).Select(e =>
|
|
{
|
|
var currentObject = e.CurrentValues.ToObject();
|
|
return new ChangeEntry
|
|
{
|
|
EntityState = e.State,
|
|
Entity = e.Entity,
|
|
EntityType = e.CurrentValues.EntityType.ClrType,
|
|
ChangeProperties = e.CurrentValues.Properties.Select(p => new ChangePropertyInfo()
|
|
{
|
|
PropertyInfo = p.PropertyInfo,
|
|
CurrentValue = p.PropertyInfo.GetValue(currentObject),
|
|
IsPrimaryKey = p.IsPrimaryKey(),
|
|
IsForeignKey = p.IsForeignKey(),
|
|
}).ToList()
|
|
};
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取移除的实体信息
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="db"></param>
|
|
/// <returns></returns>
|
|
public static IEnumerable<ChangeEntry> GetRemoved<T>(this DbContext db)
|
|
{
|
|
return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Deleted && e.Entity is T).Select(e =>
|
|
{
|
|
var originalObject = e.OriginalValues.ToObject();
|
|
return new ChangeEntry
|
|
{
|
|
EntityState = e.State,
|
|
Entity = e.Entity,
|
|
EntityType = e.OriginalValues.EntityType.ClrType,
|
|
ChangeProperties = e.OriginalValues.Properties.Select(p => new ChangePropertyInfo()
|
|
{
|
|
PropertyInfo = p.PropertyInfo,
|
|
OriginalValue = p.PropertyInfo.GetValue(originalObject),
|
|
IsPrimaryKey = p.IsPrimaryKey(),
|
|
IsForeignKey = p.IsForeignKey(),
|
|
}).ToList()
|
|
};
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取移除的实体信息
|
|
/// </summary>
|
|
/// <param name="db"></param>
|
|
/// <returns></returns>
|
|
public static IEnumerable<ChangeEntry> GetRemoved(this DbContext db)
|
|
{
|
|
return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Deleted).Select(e =>
|
|
{
|
|
var originalObject = e.OriginalValues.ToObject();
|
|
return new ChangeEntry
|
|
{
|
|
EntityState = e.State,
|
|
Entity = e.Entity,
|
|
EntityType = e.OriginalValues.EntityType.ClrType,
|
|
ChangeProperties = e.OriginalValues.Properties.Select(p => new ChangePropertyInfo()
|
|
{
|
|
PropertyInfo = p.PropertyInfo,
|
|
OriginalValue = p.PropertyInfo.GetValue(originalObject),
|
|
IsPrimaryKey = p.IsPrimaryKey(),
|
|
IsForeignKey = p.IsForeignKey(),
|
|
}).ToList()
|
|
};
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取所有的变更信息
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="db"></param>
|
|
/// <returns></returns>
|
|
public static IEnumerable<ChangeEntry> GetAllChanges<T>(this DbContext db)
|
|
{
|
|
return GetChanges<T>(db).Union(GetAdded<T>(db)).Union(GetRemoved<T>(db));
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取所有的变更信息
|
|
/// </summary>
|
|
/// <param name="db"></param>
|
|
/// <returns></returns>
|
|
public static IEnumerable<ChangeEntry> GetAllChanges(this DbContext db)
|
|
{
|
|
return GetChanges(db).Union(GetAdded(db)).Union(GetRemoved(db));
|
|
}
|
|
}
|
|
|
|
public class ChangePropertyInfo
|
|
{
|
|
/// <summary>
|
|
/// 属性
|
|
/// </summary>
|
|
public PropertyInfo PropertyInfo { get; set; }
|
|
|
|
/// <summary>
|
|
/// 原始值
|
|
/// </summary>
|
|
public object OriginalValue { get; set; }
|
|
|
|
/// <summary>
|
|
/// 新值
|
|
/// </summary>
|
|
public object CurrentValue { get; set; }
|
|
|
|
/// <summary>
|
|
/// 是否是主键
|
|
/// </summary>
|
|
public bool IsPrimaryKey { get; set; }
|
|
|
|
/// <summary>
|
|
/// 是否是外键
|
|
/// </summary>
|
|
public bool IsForeignKey { get; set; }
|
|
}
|
|
|
|
public class ChangeEntry
|
|
{
|
|
/// <summary>
|
|
/// 所属实体
|
|
/// </summary>
|
|
public object Entity { get; set; }
|
|
|
|
/// <summary>
|
|
/// 实体类型
|
|
/// </summary>
|
|
public Type EntityType { get; set; }
|
|
|
|
/// <summary>
|
|
/// 变更类型
|
|
/// </summary>
|
|
public EntityState EntityState { get; set; }
|
|
|
|
/// <summary>
|
|
/// 字段变更信息
|
|
/// </summary>
|
|
public List<ChangePropertyInfo> ChangeProperties { get; set; }
|
|
} |