fluentsprings / ExpressMapper

Mapping .Net types
http://www.expressmapper.org
Other
310 stars 65 forks source link

Stack overflow with self references, reuse of identical objects #78

Open nooxnet opened 8 years ago

nooxnet commented 8 years ago

I'm new to MVC and when I looked into object mappers I found ExpressMapper to be fast and actively developed.

It seems like ExpressMapper is not aware of identical objects in the source object structure. If a single object is referenced multiple times a new mapped object is created for every reference. This also leads to a stack overflow if an object references itself.

Did I miss a setting which enables something like object tracking to reuse identical objects?

As I'm new to these mappers I'm not sure if other object mappers are capable of this. And if this is considered a bug or a missing feature.

In my case most of my entities have a reference to UserChanged/UserCreated. Even the user itself. So some user reference themselves:

// EF entities:
public class BaseEntity
{
    public int Id { get; set; }
    public User UserCreated { get; set; }
}

public class User : BaseEntity
{
    public string Name { get; set; }
}

// ViewModels:
public class BaseEntityViewModel
{
    public int Id { get; set; }
    public UserViewModel UserCreated { get; set; }
}

public class UserViewModel : BaseEntityViewModel
{
    public string Name { get; set; }
}

public class Test3ExpressMapperMain
{
    public Test3ExpressMapperMain()
    {
        Mapper.Register<User, UserViewModel>();
        Mapper.Compile();

        var user = new User() { Id = 1, Name = "First User" };
        // remove this line and it's ok:
        user.UserCreated = user;

        var userViewModel = user.Map<User, UserViewModel>();

        Console.Write(userViewModel.Name);
        Console.ReadLine();
    }
}

I have a couple of workarounds to my problem.

But maybe this is something that should be considered. Keeping track of the mapped objects will definitely have an impact on performance. If it's not needed a negative one. But if we have a long list of objects which reference a few other objects it has most probably a positive impact as much less objects have to be created. Maybe it could be an option on the mappings level?

If it's not something to consider I'd suggest a max recursion depth setting with an exception.

natalisxx commented 8 years ago

Having the same problem.. Surprised there is no documented approach to deal with this common issue. I've invested a lot of time trying to figure out a solution that works in all cases. When a parent object has a collection of child objects and the child objects have a member reference to the parent the overflow happens when mapping the children. It would be great if there was a parameter that you could pass into Map() that you could specify which members to ignore, overriding the registered ones or simply a switch that told the mapper to ignore all child collections. If I'm missing something and there's a simple solution to this Please explain. Thanks!

OptimationClive commented 8 years ago

You can just ignore the property Mapper.Register<ApplicationDto, Application>() .Ignore(x => x.Partner)

However this doesn't really help if you actually want it mapped, I have the same issue You can play with .Before as well, however only seems to work for single objects not lists.

Mapper.Register<Question, QuestionDto>() .Before((src, dst) => dst.ParentQuestion = Mapper.Map<Question, QuestionDto>(src.ParentQuestion));

Be great if there was a solution, however we have managed for now to not map the objects, just the Id's

anisimovyuriy commented 8 years ago

Thanks a lot guys for your patience - it's coming soon!

nitingupta4u commented 8 years ago

Hi Yuriy,

Could you please let us know when can we expect this feature to be released in near future. This is very common scenario where parent has a collection of children and child has reference to parent in entity framework to work correctly in disconnected mode.

It would be really helpful if you can give us an idea about the release date with this fix.

Thanks, Nitin Gupta

anisimovyuriy commented 8 years ago

Hi @nitingupta4u,

First of all thanks a lot of your valuable input! Second - my apologies for postponing v2 release as I didn't have time recently to contribute to Expressmapper at all. But I'm planning to do it realistically next month as a priority number 1.

Thanks, Yuriy