将数据映射到相应的属性订单

时间:2018-01-22 20:15:30

标签: c# automapper

我必须使用PropertyOrderAttribute

将几个excel表读入类中
    [PropertyOrder(2)]
    public string B { get; set; }
    [PropertyOrder(1)]
    public string A { get; set; }

遵循“手写”Mapper完成工作:

    public static void MapByOrder<T, U>(T aObject, int aOrder, U aValue)
    {
        foreach (var p in aObject.GetType().GetProperties())
        {
            var pm = p.GetCustomAttributes(false)
                .FirstOrDefault(a => a.GetType() == typeof(PropertyOrderAttribute));
            if (pm != null && (pm as PropertyOrderAttribute).Order == aOrder && p.PropertyType == typeof(U))
                p.SetValue(aObject, aValue);
        }
    }

我想知道,如果像automapper这样的mapper工具也可以解决这种情况吗?

1 个答案:

答案 0 :(得分:0)

没有基于属性顺序的自动映射方式。但是,您可以创建一个ITypeConverter,它使用PropertyOrder属性(或其他确定性的查找正确顺序的方式)来在类型之间进行映射。这是一个简单的示例,如果您需要映射到多个目标类型,则可能会使目标类型成为通用:

class PropertyOrderAttribute : Attribute
{
    private readonly int order;

    public PropertyOrderAttribute(int order)
    {
        this.order = order;
    }

    public int Order => order;
}

class Ordered
{
    [PropertyOrder(3)]
    public int A { get; set; }
    [PropertyOrder(1)]
    public string B { get; set; }
    [PropertyOrder(2)]
    public DateTime C { get; set; }
}

class Spreadsheet
{
    public object[] Cells { get; set; }
}

class OrderedConverter : ITypeConverter<Spreadsheet, Ordered>
{
    public Ordered Convert(Spreadsheet source, Ordered destination, ResolutionContext context)
    {
        var properties = typeof(Ordered).GetProperties()
            .Where(property => Attribute.IsDefined(property, typeof(PropertyOrderAttribute)))
            .Select(property => new { Attribute = property.GetCustomAttributes(typeof(PropertyOrderAttribute), true).OfType<PropertyOrderAttribute>().Single(), Property = property })
            .OrderBy(orderdProperty => orderdProperty.Attribute.Order)
            .ToArray();

        if (destination == null)
        {
            destination = new Ordered();
        }

        for (var i = 0; i < source.Cells; i += 0)
        {
            properties[i].Property.SetValue(destination, source.Cells[i]);
        }

        return destination;
    }
}

AutoMapper.Mapper
    .CreateMap<Spreadsheet, Ordered>()
    .ConvertUsing(new OrderedConverter());