实体框架DbSet反射

本文关键字:反射 DbSet 框架 实体 | 更新日期: 2023-09-27 18:11:36

我正在尝试循环我的DbContext中包含具有特定基本类型的实体的所有dbset。我的目标是在调用DbContext上的SaveChanges并设置一些默认参数之前使用这个循环。

在c#中,我的基类是这样的:-
public abstract class TrackedEntity
{
    public string ModifiedBy { get; set; }
    public DateTime Modified { get; set; }
}

派生类的一个例子是:-

public class Record : TrackedEntity
{
    [Key]
    public int ID { get; set; }
    public string Name { get; set; }
}

我已经在我的DbContext类中创建了一个自定义SaveChanges方法,并且可以为包含TrackedEntity的每个DbSet获得ProtertyInfo列表,但是当我试图通过每个DbSet中的值循环时,我得到一个错误,因为我不能转换派生类的DbSet(例如DbSet<记录>)到基类的DbSet(例如DbSet)。

public class MyContext : DbContext
{
    public DbSet<Record> Records { get; set; }
    public int SaveChanges(string username)
    {
        //Set TrackedEnity update columns
        foreach (PropertyInfo property in GetDbSetPropertyInfos<TrackedEntity>())
        {
            foreach (TrackedEntity entity in (DbSet<TrackedEntity>)property.GetValue(this, null)) //fails here due to cast
            {
                entity.Modified = DateTime.UtcNow;
                entity.ModifiedBy = username;
            }
        }
        return base.SaveChanges();
    }
    //return a list of PropertyInfo for each DbSet with a given type in this context
    IEnumerable<PropertyInfo> GetDbSetPropertyInfos<T>() where T : class
    {
        IEnumerable<PropertyInfo> properties = GetType().GetProperties().Where(p => p.PropertyType.IsGenericType
            && p.PropertyType.Name.StartsWith("DbSet")
            && p.PropertyType.GetGenericArguments().Length > 0
            && p.PropertyType.GetGenericArguments()[0].IsSubclassOf(typeof(T)));
        return properties;
    }
}

有谁知道我想要实现的是可能的吗?

实体框架DbSet反射

您应该使用ChangeTracker。

....
foreach( var entry in context.ChangeTracker.Entries<TrackedEntity>())
{
    if(entry.State!=EntityState.Unchanged)
    {
        TrackedEntity entity = entry.Entity;
        entity.Modified = DateTime.UtcNow;
        entity.ModifiedBy = username;
    }
}
context.SaveChanges();