如果我有两个这样的班级:
1-ParentViewModel:
public class ParentViewModel
{
public Guid Id { get; set; }
public string Name { get; set; }
public IList<ChildViewModel> Children { get; set; }
}
2- ChildViewModel
public class ChildViewModel
{
public Guid? Id { get; set; }
public string Name { get; set; }
public Guid? ParentViewModelId { get; set; }
}
我有两个等效的父级域模型:
Icollection<Child>
代替IList<ChildViewModel>
我想从父视图模型映射到父域(包括子级映射),反之亦然,从域到包含嵌套子项的视图模型?
答案 0 :(得分:0)
您始终可以手动/繁琐地映射属性,但是,如果需要更通用的解决方案,则可以使用反射来按名称映射属性并处理集合的特殊情况。
*注意: 1.对于属于接口集合类型的属性,这将失败,但是您可以稍微调整代码以处理该问题。 2.未添加错误处理 3.这会尝试按名称映射属性,因此域类和视图模型类必须具有相同的prop名称。 4.它将跳过在目标类上找不到的属性
public class ObjectMapper
{
public void MapObject(object source, object destination)
{
var srcType = source.GetType();//get source type
var srcProps = srcType.GetProperties();//get src props, supply appropriate binding flags
var destType = destination.GetType();//get dest type
var destProps = destType.GetProperties();//get dest props, supply appropriate binding flags
foreach (var prop in srcProps)
{
//find corresponding prop on dest obj
var destProp = destProps.FirstOrDefault(p => p.Name == prop.Name);
//only map if found on dest obj
if (destProp != null)
{
//get src value
var srcVal = prop.GetValue(source);
//get src prop type
var propType = prop.PropertyType;
//get dest prop type
var destPropType = destProp.PropertyType;
//special case for collections
if (typeof(IList).IsAssignableFrom(propType))
{
//instantiate dest collection
var newCollection = (IList)Activator.CreateInstance(destPropType);
//get source collection
var collection = (IList)srcVal;
//get dest collection element type
var elementType = destPropType.GetGenericArguments().FirstOrDefault();
//iterate collection
foreach (var element in collection)
{
//instantiate element type
var tempElement = Activator.CreateInstance(elementType);
//call map object on each element
MapObject(source: element, destination: tempElement);
//add mapped object to new collection
newCollection.Add(tempElement);
}
//set dest object prop to collection
destProp.SetValue(destination, newCollection);
}
else
{
destProp.SetValue(destination, srcVal);
}
}
}
}
}