如何映射父类,包括它们的嵌套子类

问题描述 投票:0回答:1

如果我有两个这样的类:

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>

我想从父视图模型映射到父域(包括子映射),反之亦然从域到视图模型,包括嵌套子项?

c# mapping automapper ienumerable icollection
1个回答
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);
                }
            }
        }
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.