如果我有两个这样的类:
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>
我想从父视图模型映射到父域(包括子映射),反之亦然从域到视图模型,包括嵌套子项?
您可以随时手动/繁琐地映射属性,但是,如果您需要更通用的解决方案,可以使用反射按名称映射属性并处理集合的特殊情况。
*注意: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);
}
}
}
}
}