我想用模型对象值更新数据库对象 我如何获得作为List的modelObject内的属性值?
想象一下像这样的对象
public class Worker{
public string Id { get; set; }
public bool GoodPerson { get; set; }
public bool Wise { get; set; }
public List<string> Formation { get; set; }
}
我不知道如何从Formation属性中获取值,因此如何将Formation属性中的已编辑值反映到我的dataBaseObject中,您能帮助我吗?
我如何使用反射来反映这些变化?
public static void UpdateObjectFrom(this object modelObject, object dataBaseObject, string[] excludedProperties = null)
{
//WHAT IF THE modelObject is now List<string> ?????, how do i pass the values of modelObject for the dataBaseObject List<string> object
Type modelObjectType = modelObject.GetType();
Type dataBaseObjectType = dataBaseObject.GetType();
PropertyInfo[] modelProperties = modelObjectType.GetProperties();
PropertyInfo[] dataBaseProperties = dataBaseObjectType.GetProperties();
if (excludedProperties != null)
{
dataBaseProperties = dataBaseProperties.Where(x => !excludedProperties.Contains(x.Name)).ToArray();
}
foreach (PropertyInfo dataBasePropInfo in dataBaseProperties)
{
if (HasSimpleType(dataBasePropInfo.PropertyType) || dataBasePropInfo.PropertyType.IsGenericType && dataBasePropInfo.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
PropertyInfo modelPropInfo = modelObjectType.GetProperty(dataBasePropInfo.Name);
dataBasePropInfo.SetValue(dataBaseObject, modelPropInfo.GetValue(modelObject));
}
else if (dataBasePropInfo.PropertyType.IsGenericType)
{
UpdateObjectFrom(dataBasePropInfo.GetValue(dataBaseObject, null), modelObjectType.GetProperty(dataBasePropInfo.Name).GetValue(modelObject, null));
}
else if (dataBasePropInfo.PropertyType.IsClass && !dataBasePropInfo.PropertyType.FullName.StartsWith("System."))
{
UpdateObjectFrom(dataBasePropInfo.GetValue(dataBaseObject, null), modelObjectType.GetProperty(dataBasePropInfo.Name).GetValue(modelObject, null));
}
}
}
private static bool HasSimpleType(Type tipo)
{
return tipo.IsPrimitive || tipo == typeof(string) || tipo.IsEnum || tipo == typeof(Decimal) || tipo == typeof(DateTime);
}
答案 0 :(得分:0)
在您进一步阅读之前,我建议您查看AutoMapper。 AutoMapper旨在将数据从一种类型映射到另一种类型。从我看来,这就是你想要完成的事情。
需要注意的一点是,AutoMapper不会对列表执行深层复制。因此,如果修改源对象上的列表,它将影响目标对象上的列表。
浅拷贝是直接的,只是直接复制列表,就像你的原始和可空类型一样。
您的代码需要考虑的其他因素。您正在检查属性名称,但不检查两个对象的类型。如果您在另一个课程int Id
上有string Id
该怎么办?
如果您必须拥有该列表的深层副本,则会变得更复杂一些。但这是我想出的(注意:这不是一个真正的深层副本,因为列表的成员没有被克隆):
else if (dataBasePropInfo.PropertyType.IsGenericType)
{
var args = dataBasePropInfo.PropertyType.GetGenericArguments();
var lstType = typeof (List<>).MakeGenericType(args);
if (lstType.IsAssignableFrom(dataBasePropInfo.PropertyType))
{
PropertyInfo modelPropInfo = modelObjectType.GetProperty(dataBasePropInfo.Name);
var target = Activator.CreateInstance(lstType);
var source = modelPropInfo.GetValue(modelObject);
lstType.InvokeMember("AddRange", BindingFlags.InvokeMethod, null, target, new[] {source});
dataBasePropInfo.SetValue(dataBaseObject, target);
}
else
{
UpdateObjectFrom(dataBasePropInfo.GetValue(dataBaseObject, null), modelObjectType.GetProperty(dataBasePropInfo.Name).GetValue(modelObject, null));
}
}
推荐阅读:How to: Examine and Instantiate Generic Types with Reflection
您可以使用反射和序列化的组合。
dataBasePropInfo.SetValue(dataBaseObject,
modelPropInfo.GetValue(modelObject));