按字符串引用对象的属性

时间:2014-04-28 14:19:18

标签: c# entity-framework

是否可以通过其键名调用对象的属性?

我想从Cookie中的数据更新用户的个人资料。所以我有以下代码

bool PropertyChanged = false;
UserProfile ThisUserProfile = context.UserProfiles.Single(u => u.Id == int.Parse(GetCookieValue(UserIdString)));
if(ThisUserProfile.Property1 != GetCookieValue("Property1")){
    ThisUserProfile.Property1 = GetCookieValue("Property1")
    PropertyChanged = true
}
if(ThisUserProfile.Property2 != GetCookieValue("Property2")){
    ThisUserProfile.Property2 = GetCookieValue("Property2")
    PropertyChanged = true
}
if(ThisUserProfile.Property3 != GetCookieValue("Property3")){
    ThisUserProfile.Property3 = GetCookieValue("Property3")
    PropertyChanged = true
}

// and many more properties.....

if(PropertyChanged)
    context.SaveChanges();

是否可以编写一个方法来更新属性对象,如下所示?

void UpdateIfChanged(string Key){
    ThisUserProfile[key] = GetCookieValue("key")
    PropertyChanged = true
}

所以我可以创建一个字符串数组并使用foreach循环一次完成所有操作吗?

1 个答案:

答案 0 :(得分:2)

你可以使用一些反思。

public static void SetValue(object entity, string propertyName, object value)
{
            try
            {
                PropertyInfo pi = entity.GetType().GetProperty(propertyName);
                Type t = Nullable.GetUnderlyingType(pi.PropertyType) ?? pi.PropertyType;
                object safeValue = (value == null) ? null : Convert.ChangeType(value, t);
                pi.SetValue(entity, safeValue, null);
            }
            catch (InvalidCastException ex)
            {
                //Handle casting between different assemblies...
                try
                {
                    PropertyInfo pi = entity.GetType().GetProperty(propertyName);
                    Type t = Nullable.GetUnderlyingType(pi.PropertyType) ?? pi.PropertyType;
                    object safeValue = (value == null) ? null : Activator.CreateInstance(t, value);
                    pi.SetValue(entity, safeValue, null);
                }
                catch
                {

                }
            }
            catch
            {

            }

            return;
}

然后使用这样的方法:

string[] userProperties = {"Username", "Email", "Address"};

foreach (string s in userProperties)
{
    //You could set up your application so cookie property names are the same as your entity's...
    SetValue(ThisUserProfile, s, value);
}

同时根据您的需要调整try/catch SetValue块。您尚未指定ThisUserProfile的类型,因此我无法完全测试此功能是否适用于您的特定情况。

你应该知道反射是慢的,所以只有你确实需要时才使用它。

由于您正在使用实体框架而您没有使用实体的通常set访问者(通知更改跟踪器正在进行的更改),您可能必须将实体的State属性设置为{{1在提交更改(EntityState.Modified)之前自己。

如果您打算使用反射从另一个对象中检索值

,那么

SaveChanges也可能有用

GetValue