使用Reflection为所有子类设置属性名称的值

时间:2015-11-19 17:44:42

标签: c# entity-framework system.reflection

所以我有一个属性CreatedOn和ModifiedOn 我的大多数课程都存在

有时我需要签入一个对象,如果还有一个尚未设置的日期

所以我使用这种方法

    public void setDateTimeIfNotSet(object p)
    {
        if (p == null) return;
        Type t = p.GetType();
        foreach (PropertyInfo info in t.GetProperties())
        {
            if ((info.Name == "CreatedOn" || info.Name == "ModifiedOn") && info.CanWrite && (DateTime)info.GetValue(p,null) == default(DateTime))
            {
                info.SetValue(p, DateTime.UtcNow, null);
            }
        }
    }

它工作正常但仅适用于第一级属性 比如object.ModifiedOn

但我需要它通过所有子对象 像

object.subobject.ModifiedOn
object.subobject2.ModifiedOn
object.subobject.subsubobject.ModifiedOn

3 个答案:

答案 0 :(得分:3)

这不是您问题的真正答案,但可能是您问题的解决方案。

您确定要使用反射设置这些属性吗?为什么不确保所有类在使用ChangeTracker上的实体框架DbContext保存到数据库时获取这些属性集。

您可以通过覆盖上下文的SaveChanges来完成此操作:

public override int SaveChanges()
{
    var entries = this.ChangeTracker.Entries()
        .Where(e => e.State == EntityState.Added || e.State == EntityState.Modified);

    foreach(var entry in entries)
    {
        if(entry.State == EntityState.Added)
        {
            entry.Property("CreatedOn").CurrentValue = DateTime.UtcNow;
        }
        else 
        {
            entry.Property("ModifiedOn").CurrentValue = DateTime.UtcNow;
        }
    }
    return base.SaveChanges();
}

答案 1 :(得分:1)

为什么不使用递归?

void Method(Type t)
{
    foreach (PropertyInfo info in t.GetProperties())
    {
        if ((info.Name == "CreatedOn" || info.Name == "ModifiedOn") && info.CanWrite && (DateTime)info.GetValue(p,null) == default(DateTime))
        {
            info.SetValue(p, DateTime.UtcNow, null);
        }
        Method(info.PropertyType);
    }
}

此代码未经过测试,因此使用风险自负。

答案 2 :(得分:1)

如果你真的想使用循环并处理它...那么试试这个..

public static void SetDateTimeIfNotSet(object p)
{
    Type t = p.GetType();
    t.GetProperties()
        .Where(c=>c.PropertyType.IsClass || c.PropertyType == typeof(DateTime))
        .ToList().ForEach(c =>
    {
        object child = c.GetValue(p);

        if (c.PropertyType == typeof (DateTime))
        {
            if(string.Equals(c.Name, "CreatedOn"))
            if((DateTime)child == default(DateTime))
            c.SetValue(p, DateTime.Now);
        }
        else
        {                    
            if(child!=null)
                SetDateTimeIfNotSet(c.GetValue(p));
        }
    });
}

小提琴 https://dotnetfiddle.net/1JycJ2