简体   繁体   中英

Can you do a specific action with all non mapped properties using automapper?

I'm implementing an import feature that will read a spreadsheet file and save all rows as records on a DB . I already have code in place that transforms the spreadsheet into a DataSet .

The problem I have right now is that the class I need to deserialize the DataRows to is something like this:

public class Product
{
    public string Name { get; set; }

    // More Props

    public IDictionary<string, object> Specifications { get; set; }
}

And each DataRow will have all the Product properties and some extra that have to be added into the Specifications Dictionary .

Is there a way to configure AutoMapper to map all non existent properties in the destination into a new item on the Specifications Dictionary ?

You can't do a specific action but you can create a custom mapping which finds all unmapped properties and adds them to the destination dictionary.

This is a little trickier because you are mapping from a DataRow , rather than a normal class, but it can be done. In your resolution method for Specifications , you need to loop through the columns of the DataTable and check if there is a mapping for a property with that name. If not add it to the dictionary:

    private static void ConfigureMappings()
    {
        Mapper.CreateMap<DataRow, Product>()
            .ForMember(p => p.Name, mo => mo.MapFrom(row => row["Name"]))
            .ForMember(p => p.ID, mo => mo.MapFrom(row => row["ID"]))
            .ForMember(p => p.Specifications, mo => mo.ResolveUsing(MapSpecifications));
    }

    private static object MapSpecifications(ResolutionResult rr, DataRow row)
    {
        Dictionary<string, object> specs = new Dictionary<string, object>();

        // get all properties mapped in this mapping
        var maps = rr.Context.Parent.TypeMap.GetPropertyMaps();

        // loop all columns in the table
        foreach (DataColumn col in row.Table.Columns)
        {
            // if no property mapping exists, get value and add to dictionary
            if (!maps.Any(map => map.DestinationProperty.Name == col.ColumnName))
            {
                specs.Add(col.ColumnName, row[col.ColumnName]);
            }
        }

        return specs;
    }

Sample dotnetFiddle

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM