简体   繁体   English

实体框架DbSet反射

[英]Entity Framework DbSet Reflection

I am trying to loop through all the DbSets in my DbContext that contain entities with a certain base type. 我试图遍历我的DbContext中包含具有特定基类型的实体的所有DbSet。 My aim is to use this loop before I call SaveChanges on my DbContext and set some default parameters. 我的目标是在我在DbContext上调用SaveChanges并设置一些默认参数之前使用此循环。

In C#, my base class looks like this:- 在C#中,我的基类看起来像这样:

public abstract class TrackedEntity
{
    public string ModifiedBy { get; set; }

    public DateTime Modified { get; set; }
}

An example of a derived class is:- 派生类的一个例子是: -

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

    public string Name { get; set; }
}

I have created a custom SaveChanges method in my DbContext class and can get a list of ProtertyInfo for each DbSet containing a TrackedEntity, but when I try to loop through the values in each DbSet I get an error as I can't cast my DbSet of derived class (eg DbSet< Record >) to a DbSet of the base class (eg DbSet< TrackedEntity >). 我在我的DbContext类中创建了一个自定义的SaveChanges方法,并且可以为包含TrackedEntity的每个DbSet获取一个ProtertyInfo列表,但是当我尝试遍历每个DbSet中的值时,我得到一个错误,因为我无法投射我的DbSet派生类(例如DbSet <Record>)到基类的DbSet(例如DbSet <TrackedEntity>)。

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;
    }
}

Does anyone know if what I am trying to achieve is possible? 有谁知道我想要实现的目标是否可行?

You should use ChangeTracker instead. 您应该使用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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM