Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PreserveReference and "An item with the same key has already been added." ArgumentException #102

Closed
nsgaga opened this issue Feb 14, 2017 · 5 comments

Comments

@nsgaga
Copy link

nsgaga commented Feb 14, 2017

I'm having an issue with PreserveReference, I worked around it and I pretty much stopped using it, but I'd like to know if I'm missing something (which is likely).

  • so, when I have circular references PreserveReference didn't resolve that for me

  • and when I have (what seems as, it's hard to trace it, I didn't debug it with Mapster source, will do if needed) 2 properties pointing to the same object reference - then I get the above error (which is a typical dictionary/hash issue somewhere inside the Mapster code).

  • so it's simple hierarchy that I'm trying to map (basically entities to view-models, pretty typical), no circular references (I made sure of that, the code is quite mature)

  • what it's supposed to actually handle (2 properties pointing to the same object) is when it fails (that error)

  • as soon as I remove the PreserveReference all is working (just not preserved references of course)

I'll try and dive deeper into this, provide a sample solution etc.,
but I just wanted to see if this is a known issue, or even if you ever encountered it, or it's something specific to my data/code.

@chaowlert
Copy link
Collaborator

Hi,

I tried to reproduce, but it works fine. Could you pls provide reproducible code?

public class ParentPoco
{
    public ChildPoco Child1 { get; set; }
    public ChildPoco Child2 { get; set; }
}
public class ChildPoco
{
    public Guid Id { get; set; }
}
public class ParentDto
{
    public ChildDto Child1 { get; set; }
    public ChildDto Child2 { get; set; }
}
public class ChildDto
{
    public Guid Id { get; set; }
}
class Program
{
    static void Main(string[] args)
    {
        TypeAdapterConfig.GlobalSettings.Default.PreserveReference(true);
        var child = new ChildPoco {Id = Guid.NewGuid()};
        var poco = new ParentPoco {Child1 = child, Child2 = child};
        var result = poco.Adapt<ParentDto>();
        Console.WriteLine(result.Child1 == result.Child2); //true
    }
}

@nsgaga
Copy link
Author

nsgaga commented Feb 14, 2017

thanks on your response,
I thought it wasn't simple issue,
I certainly will sit down and make a small project - it's part of a larger scenario, but I'll figure something out.
This is how I'm using it, as a start only (that's the offending code)

    config.NewConfig<ISomeEntity, SomeViewModel>()  
        .ConstructUsing(entity => container.Resolve<SomeViewModel.Factory>()(entity))  
        .IgnoreAttribute(typeof(DoNotMapAttribute))  
        .IgnoreNullValues(true)  
        .PreserveReference(true);

...but I should know better, I'll provide an example.
I basically just wanted to get a first response to see if it's worth investing time into it.

@chaowlert
Copy link
Collaborator

I have no clue why PreserveReference doesn't work in your case. Mapster checks item not exists before adding new item to dictionary. My guess is there might be some other issues that cause the problem.

@nsgaga
Copy link
Author

nsgaga commented Mar 23, 2017

And just to update, I didn't have enough time but I figured out where the problem is, roughly, I have hierarchical data structure and I was applying TypeAdapter.Adapt redundantly at every level, i.e. not just on the root but also on each child (building, again, it's own hierarchy). If I de-duplicate that and just have one mapping on the root (that takes care of the entire hierarchy) the issue goes away. Exception is somewhere within the expressions created, but it's hard to debug those.
That isn't wrong though per se (even though arguably that wasn't the best design decision on my part), and I'm guessing it should not throw.
I'm going to write a small unit test with some sample data that mimics the above case - and will post that - but need a bit more time to find some space to do it. So I didn't forget about it!

@chaowlert
Copy link
Collaborator

Hi, even I don't know root cause of this problem. I changed from Dictionary.Add to Dictionary[key] when adding new references to solve this issue. If you can provide test case, I'm happy to inspect the problem. I will close this issue for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants