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

Problem with mapping nested objects having the same property names as parent object #138

Open
mszymczakowski opened this issue Apr 9, 2017 · 1 comment
Assignees

Comments

@mszymczakowski
Copy link

mszymczakowski commented Apr 9, 2017

Hi

I've found a problem with mapping objects, that have nested object with properties named the same as in parent object.

For example, I have classes: Class1 and Class2 that have child objects under property Inner (Class1Inner and Class2Inner).

Class1:

public class Class1
{
	public int Id { get; set; }

	public string Name { get; set; }

	public Class1Inner Inner { get; set; }


	public class Class1Inner
	{
		public int Id { get; set; }

		public string Name { get; set; }
	}

	public override string ToString()
	{
		return $"[Class1][[Id: {Id}][Name: {Name}][Inner: [Id: {Inner.Id}][Name: {Inner.Name}]]]";
	}
}

Class2:

public class Class2
{
	public int Id { get; set; }

	public string Name { get; set; }

	public Class2Inner Inner { get; set; }


	public class Class2Inner
	{
		public int Id { get; set; }

		public string Name { get; set; }
	}

	public override string ToString()
	{
		return $"[Class2][[Id: {Id}][Name: {Name}][Inner: [Id: {Inner.Id}][Name: {Inner.Name}]]]";
	}
}

I have mapping:

public static void RegisterMapping()
{
	Mapper.Register<Class1, Class2>()
		.Before((src, dest) =>
		{
			dest.Inner = new Class2.Class2Inner();
		})
		.Member(dest => dest.Id, src => src.Id)
		.Member(dest => dest.Name, src => src.Name)
		.Member(dest => dest.Inner.Id, src => src.Inner.Id)
		.Member(dest => dest.Inner.Name, src => src.Inner.Name);
}

And when I execute code below:

RegisterMapping();

var class1Element = new Class1()
{
	Id = 1,
	Name = "First",
	Inner = new Class1.Class1Inner()
	{
		Id = 11,
		Name = "First Inner"
	}
};

Console.WriteLine($"Element before mapping: {class1Element}");

var class2Element = class1Element.Map<Class1, Class2>();

Console.WriteLine($"Element after mapping: {class2Element}");

The result is:

Element before mapping: [Class1][[Id: 1][Name: First][Inner: [Id: 11][Name: First Inner]]]
Element after mapping: [Class2][[Id: 0][Name: ][Inner: [Id: 11][Name: First Inner]]]

Properties in Class2 were not mapped, but in Class2Inner were mapped correctly.

But when I change mapping to (I just moved inner class mapping to the top of the mapping sequence):

public static void RegisterMapping()
{
	Mapper.Register<Class1, Class2>()
		.Before((src, dest) =>
		{
			dest.Inner = new Class2.Class2Inner();
		})
		.Member(dest => dest.Inner.Id, src => src.Inner.Id)
		.Member(dest => dest.Inner.Name, src => src.Inner.Name)
		.Member(dest => dest.Id, src => src.Id)
		.Member(dest => dest.Name, src => src.Name);
}

The result is:

Element before mapping: [Class1][[Id: 1][Name: First][Inner: [Id: 11][Name: First Inner]]]
Element after mapping: [Class2][[Id: 1][Name: First][Inner: [Id: 11][Name: First Inner]]]

So everything is perfectly fine.

Additional informations:
Expressmapper version: 1.9.1 (from NuGet)
.NET Framework version: 4.6.2

@SuheylZ
Copy link

SuheylZ commented Sep 28, 2017

I have found a similar problem with mapper but in a bit different context, I have the following class declaration:


    public class MyEditModel
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public string Notes { get; set; }

        public DropDownList<int> Authorized1 { get; set; } = new DropDownList<int>();
        public DropDownList<int> Authorized2 { get; set; } = new DropDownList<int>();
    }

and here is the DropDownList class:
` public class DropDownList: DropDownListBase
where SelectionType : IComparable
{
SelectionType _selection;

    public SelectionType Selection
    {
        get => _selection;
        set
        {
            _selection = value;
            if (Items.Any())
            {
                foreach (var item in Items)
                {
                    if (item.Value == _selection.ToString())
                        item.Selected = true;
                    else
                        item.Selected = false;
                }
            }
        }
    }

    public DropDownList()
    {
       Selection = default(SelectionType);
    }
    public DropDownList(List<SelectListItem> list):this()
    {
        Items = list;
    }
    public DropDownList(List<SelectListItem> list, SelectionType item):this(list)
    {
        Selection = item;
    }

    public static DropDownList<SelectionType> Create<T>(IEnumerable<T> list, Expression<Func<T, string>> textExpr, Expression<Func<T, SelectionType>> valueExpr, SelectionType selected) where T:class
    {
        var items = BuildSelectItemList(list, textExpr, valueExpr);
        return new DropDownList<SelectionType>(items, selected);
    }
    public static DropDownList<SelectionType> Create<T>(IEnumerable<T> list, Expression<Func<T, string>> textExpr, Expression<Func<T, SelectionType>> valueExpr) where T:class
    {
        var items = BuildSelectItemList(list, textExpr, valueExpr);
        return new DropDownList<SelectionType>(items);
    }
   
}`

I define the mapping in the following way

p.Register<MyEditModel, Entity>()
.Member(t=>t.Authorized1.Selection, s=>s.Person1Id)
.Member(t=>t.Authorized2.Selection, s=>s.Person2Id);

Only the Selection property last set has the value. Any Selection properties set earlier loose their values.

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

No branches or pull requests

3 participants