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

TinyMapper mapping with list of entity object #32

Closed
ronakjIndusa opened this issue May 19, 2016 · 8 comments
Closed

TinyMapper mapping with list of entity object #32

ronakjIndusa opened this issue May 19, 2016 · 8 comments

Comments

@ronakjIndusa
Copy link

ronakjIndusa commented May 19, 2016

I have started using TinyMapper in my project for object-to-object mapping and got succeeded for single object to single object mapping but i stuck when i want to map the whole list of entity object to list of DTO class. Can you please help me out. I googled but didn't find any solution. Can anyone please help me out?

I am able to map single object to object by using below code:

var sq = new SurveyQuestion
            {
                SurveyId = 61,
                Question = "John",
                QuestionDescription = "Doe",
                Type = "DB",
                Selector = "TB",
                QuestionId = "QID1",
                SubSelector = "TX"
             }
TinyMapper.Bind<Survey, surveyDto>();
var result = TinyMapper.Map<surveyDto>(sq);

But i stuck when i want to map whole list of survey entity to surveyDto entity:

List<Survey> survey = _surveyRepository.All().ToList();
TinyMapper.Bind<List<Survey>, List<SurveyDto>>();
List<SurveyDto> surveyDto = TinyMapper.Map<List<SurveyDto>>(survey);

gives below error:

Cannot implicitly convert type System.Collections.Generic.List<SurveyDto>' to 'SurveyDto'

@GSerjo
Copy link
Member

GSerjo commented May 20, 2016

I'm not sure that understand what are you going to bind. Do you want to map List<T> to a single object? Could you please provide full code, unfortunately, your sample has some missing parts, it's not clear what parameters in the Bind method

Anyway, if you are going to map List<T> to List<V>, the Bind should be like this TinyMapp.Bind<List<T>, List<V>>()

@ronakjIndusa
Copy link
Author

ronakjIndusa commented May 20, 2016

Exactly, what you understand is right!!
I want to Map List to List where T is entity Object and V is my DTO object.
Here I have bind List<T> to List<V>

List <Survey> sql= _surveyRepository.All().ToList(); //Getting all data from my table in List form
TinyMapper.Bind<List<Survey>, List<SurveyDto>>();

Can you please provide me the steps to map these two list?
I tried beow lines to Map but both below line gives me error.

List<SurveyDto> surveyDto =  TinyMapper.Map<List<Survey>, List<SurveyDto>>(sql); //Error
List<SurveyDto> surveyDto = TinyMapper.Map<List<Survey>>(sql); //Error

Can you please suggest Mapping code?
Does TinyMapper suppotrs collection mapping?? Please explain me through an example.

@GSerjo
Copy link
Member

GSerjo commented May 20, 2016

yes, sure.

Call this lines some where in the application start

TinyMapper.Bind<List<Survey>, List<SurveyDto>>();

then in you logic

List <Survey> sql= _surveyRepository.All().ToList();
List<SurveyDto> surveyDto = TinyMapper.Map<List<Survey>>(sql);

here the working sample

        [Fact]
        public void Test()
        {
            var fromDatabase = new List<Survey>
            {
                new Survey { Id = 1, Data = "Data1" },
                new Survey { Id = 2, Data = "Data2" }
            };

            TinyMapper.Bind<List<Survey>, List<SurveyDto>>();

            var dto = TinyMapper.Map<List<SurveyDto>>(fromDatabase);
        }


        public sealed class Survey
        {
            public int Id { get; set; }
            public string Data { get; set; }
        }


        public sealed class SurveyDto
        {
            public int Id { get; set; }
            public string Data { get; set; }
        }

@ronakjIndusa
Copy link
Author

Many thanks for the example!! 👍 Now am able to do collection mapping successfully.
@GSerjo One more point, Can you please let me know the drawback of using TinyMapper for object to object mapping, if there is any??
and why do we use Tinymapper instead of Automapper? which one is more better for object to object mapping in overall perspective?

Thanks for raising helping hands!!

@GSerjo
Copy link
Member

GSerjo commented May 21, 2016

There are spots even in the sun :) As for me, there are following pros and cons:

TinyMapper

Pros:

  • Speed
  • Really simple API

Cons:

  • Doesn't have huge amount of mappings

AutoMapper

Pros:

  • Huge amount of mapping rules

Cons:

  • Speed
  • Huge amount of mapping rules

I added "Huge amount of mappings" to pros and cons in AutoMapper because sometimes object mapper used as a part of business logic and a code becomes too complicated. So when you don't have the option to write business logic mapping in an object mapper, a code could be clear. On the other side, some applications can have really difficult mapping rules, so the AutoMapper could be a good choice.

So, it depends on the exact issue, maybe even using several mappers could be a good decision.

@ronakjIndusa
Copy link
Author

ronakjIndusa commented May 22, 2016

@GSerjo Thanks for the detailed information!!
I just wanted to know, what kind of issues may occur in using Tinymapper when we just want to map entity object to DTO object and then DTO object to ViewModel object in application when we have simple table schema with references tables?

@ronakjIndusa
Copy link
Author

@GSerjo I am getting below exception when I try to map below two objects:
Exception: {"Not suppoerted From ICollection1 To ICollection1"}

Example:
//Target Class
public class SurveyDto 
    {
        public long SurveyId { get; set; }
        public string SurveyName { get; set; }
        public string OwnerId { get; set; }
        public bool IsActive { get; set; }
        public System.DateTime DateCreated { get; set; }
        public System.DateTime DateModified { get; set; }
        public System.DateTime StartDate { get; set; }
        public System.DateTime ExpirationDate { get; set; }
        public string Language { get; set; }

        public virtual ICollection<SurveyQuestionDto> SurveyQuestions { get; set; }
    }

//Source Class
public partial class Survey
    {
        public Survey()
        {
            this.SurveyQuestions = new HashSet<SurveyQuestion>();
        }

        public long SurveyId { get; set; }
        public string SurveyName { get; set; }
        public string OwnerId { get; set; }
        public bool IsActive { get; set; }
        public System.DateTime DateCreated { get; set; }
        public System.DateTime DateModified { get; set; }
        public System.DateTime StartDate { get; set; }
        public System.DateTime ExpirationDate { get; set; }
        public string Language { get; set; }

        public virtual ICollection<SurveyQuestion> SurveyQuestions { get; set; }
    }

In Controller:
public void GetAll()
        {
            List<Survey> survey = _surveyRepository.All().ToList();
            TinyMapper.Bind<List<Survey>, List<SurveyDto>>();
            List<SurveyDto> surveyDto = TinyMapper.Map<List<SurveyDto>>(survey); //Getting exception
        }

Please help me out.

@GSerjo
Copy link
Member

GSerjo commented May 23, 2016

The exception occurred because TinyMapper doesn't know how to map ICollection to ICollectction, i.e. it doesn't know what exact type to create (is it List<T>, Collection<T>, HashSet or etc), the same like write this code by hands. So just let TinyMapper know what to create, for instance. (I going to create more helpful error message)

        [Fact]
        public void Map_ConcreteType_Success()
        {
            TinyMapper.Bind<Source2, Target2>(config =>
            {
                config.Bind(target => target.Ints, typeof(List<int>));
                config.Bind(target => target.Strings, typeof(List<string>));
            });

            var source = new Source2
            {
                Ints = new List<int> { 1, 2, 3 },
                Strings = new List<string> { "A", "B", "C" }
            };

            var actual = TinyMapper.Map<Target2>(source);
            Assert.Equal(source.Ints, actual.Ints);
            Assert.Equal(source.Strings, actual.Strings);
        }

        public class Source2
        {
            public IList<int> Ints { get; set; }
            public List<string> Strings { get; set; }
        }

        public class Target2
        {
            public IList<int> Ints { get; set; }
            public IEnumerable<string> Strings { get; set; }
        }

About

I just wanted to know, what kind of issues may occur in using Tinymapper when we just want to map entity object to DTO object and then DTO object to ViewModel object in application when we have simple table schema with references tables?

Each application has bugs, more important how quickly it could be fixed. About TinyMapper, there're a lot of unit tests which cover the most common scenarios.

Anyway, doesn't matter what kind of mapper you choose, try to minimize usage it across all application, i.e. if there're too many Map calls in the app, may better idea is to create a wrapper above an object mapper, so the app will depend on the wrapper and not from the object mapper, so you can easily change the mapper and easily write unit tests.

@GSerjo GSerjo closed this as completed May 24, 2016
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