IEnumerable to EntityCollection failed mapping wit

2019-09-14 03:12发布

问题:

Starting with 2.2.0 I'm having a problem with nasted mapping.

I have two models which I need to map: an EntityObject model (autogenerated by EF from DB) and a simple Data Model. EntityObject model contains an EntityCollection property of another EntityObject model type, Data Model contains an IEnumerable of another Data Model type: these fields should also be mapped. As an example:

public class AnotherDataModel
{
    //Some properties
}

public class DataModel
    {
        //Some properties

        private IEnumerable<AnotherDataModel> anotherDataModel;
        public IEnumerable<AnotherDataModel> AnotherDataModel
        {
                get { return anotherDataModel ?? (anotherDataModel = new AnotherDataModel[0]); }
                set { anotherDataModel = value; }
        }
    }

public partial class AnotherModel : EntityObject
{
        //Some properties
}

public partial class Model : EntityObject
    {
        //Some properties

    public EntityCollection<AnotherModel> AnotherModel
        {
                get
                {
                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<AnotherModel>(//relationship settings);
                }
                set
                {
                if ((value != null))
                    {
                        ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<AnotherModel>(//relationship settings, value);
                    }
                }
            }
        }
    }

I need to map DataModel to Model. Both needed maps exist:

Mapper.CreateMap<AnotherDataModel, AnotherModel>();
Mapper.CreateMap<DataModel, Model>();

But while mapping DataModel to Model i'm getting an error on mapping AnotherDataModel to AnotherModel properties:

The EntityCollection has already been initialized. The InitializeRelatedCollection method should only be called to initialize a new EntityCollection during deserialization of an object graph.

it works fine on automapper 2.0. I tried UseDestinationValue for this field - but the result is the same.

I also got lots of "collection was of a fixed size" errors on mapping IEnumerable in other places, even though an issue about such trouble was closed, but i've fixed it with custom resolver:

public class EnumerableResolver<TCollectionOfInputType, TCollectionOfOutputType> : 
ValueResolver<IEnumerable<TCollectionOfInputType>, IEnumerable<TCollectionOfOutputType>>
{
    public IEnumerable<TCollectionOfOutputType> Resolve(IEnumerable<TCollectionOfInputType> source)
    {
        return this.ResolveCore(source);
    }

    protected override IEnumerable<TCollectionOfOutputType> ResolveCore(IEnumerable<TCollectionOfInputType> source)
    {
        return source == null
            ? null
            : source.Select(Mapper.Map<TCollectionOfInputType, TCollectionOfOutputType>);
    }

It doesn't work in this case. Also, mapping IEnumerable to EntityCollection while they are not nested - works fine:

Mapper.CreateMap<IEnumerable<AnotherDataModel>, EntityCollection<AnotherModel>>();

Any help would be appreciated.

回答1:

Try this,

class Program
{
    static void Main(string[] args)
    {
        Mapper.CreateMap<LocationSource, LocationDestination>();
        Mapper.CreateMap<StoreSource, StoreDestination>();

        var storeSource = new StoreSource
        {
            Name = "Worst Buy",
            Locations = new EntityCollection<LocationSource> { new LocationSource { Id = 1, Address ="abc1"},new LocationSource { Id = 2, Address ="abc2"}}
        };

        var storeDestination = Mapper.Map<StoreSource, StoreDestination>(storeSource);
    }
}

public class StoreDestination
{
    public string Name { get; set; }
    public IList<LocationDestination> Locations { get; set; }
}

public class LocationDestination
{
    public int Id { get; set; }
    public string Address { get; set; }
}

public class StoreSource
{
    public string Name { get; set; }
    public EntityCollection<LocationSource> Locations { get; set; }
}

public class LocationSource
{
    public int Id { get; set; }
    public string Address { get; set; }
}


回答2:

This was a bug in automapper which is now fixed in latest versions.

Issue on github with details just in case: https://github.com/AutoMapper/AutoMapper/issues/425