0

In my NHIbernate (Database Model) I have this :

public class Pers {
    public int Id{ get; set ;}
    public string FirstName{ get; set ;}
    public string LastName{ get; set ;}
    public string City{ get; set ;}
    public int Age{ get; set ;}

    public Role Role{ get; set ;}
}

I have some dropwon (Database mode) :

public class Role {
    public int Id{ get; set ;}
    public string NL{ get; set ;}
    public string FR{ get; set ;}
}

In my view I'd like use the dropdown and display some record (not all, in my real class there are much more properties) of Pers. I created a Dto class for Pers with the fields I need :

public class PersDto {
    public int Id{ get; set ;}
    public string FirstName{ get; set ;}
    public string LastName{ get; set ;}

    public RoleDto RoleDto{ get; set ;}
}

public class RoleDto {
    public int Id{ get; set ;}
    public string NL{ get; set ;}
    public string FR{ get; set ;}
}

In the controller :

Mapper.CreateMap<Role, RoleDto>();
myModel.RoleDto = Mapper.Map<Role, RoleDto>(roleListFromDB);

Mapper.CreateMap<Pers, PersDto>();
myModel.PersDto = Mapper.Map<Pers, PersDto>(persFromDB);

public class MyModel{
    public PersDto PersDto{ get; set ;}
    public RoleDto RoleDto{ get; set ;}
}

Is it the right way ? Or it's better to do this with creating a PersDto:

public class MyModel{
    public string FirstName{ get; set ;}
    public string LastName{ get; set ;} 
    public RoleDto RoleDto{ get; set ;}
}

Is it possible with automapper to copy only some fields and not all ?

Thanks,

TheBoubou
  • 19,487
  • 54
  • 148
  • 236

2 Answers2

2

Is it the right way ?

No, you should not call Mapper.CreateMap<TSource, TDest> in the controller. This method should be invoked only once for the entire lifetime of the AppDomain, ideally in Application_Start.

You could write a mapping profile:

public class PersonProfile : Profile
{
    protected override void Configure()
    {
        Mapper.CreateMap<Role, RoleDto>();
        Mapper.CreateMap<Pers, PersDto>();
    }
}

then in Application_Start configure those profiles:

Mapper.AddProfile(new PersonProfile());

and finally in your controller only use the Mapper.Map<TSource, TDest> method:

var myModel = new MyModel();
myModel.RoleDto = Mapper.Map<Role, RoleDto>(roleListFromDB);
myModel.PersDto = Mapper.Map<Pers, PersDto>(persFromDB);
return View(myModel);
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • I expected a little bit more explanation, it's not really clear to me. In the sample found here, it's in the controller and what about a PersDto or Perso properties in the model ? – TheBoubou Jul 18 '11 at 12:40
  • And what about the view ? The "PersDto" class has the exact same properties than "Pers" ? Possible, in some case, copy with automapper somes properties and not all ? – TheBoubou Jul 18 '11 at 12:45
  • When I want to save to database I have to get datafrom "PersDto" to "Pers" before updating DB. Darin you removed some code of your sample... was clearer. – TheBoubou Jul 18 '11 at 12:47
  • @Kris-I, in this case you will have to define bidirectional mappings. You also need to define a mapping between RoleDto and and Role and between PersDto and Pers. – Darin Dimitrov Jul 18 '11 at 12:49
  • Grrrr :) and to copy only some fields ? In the model, there are some properties than "Pers" and other for "Role" how use automapper then – TheBoubou Jul 18 '11 at 12:52
  • @Kris-I, in this case you could fetch the model from the DB first given the id, and then instead of doing `Mapper.Map(viewModel);` you would do `Mapper.Map(viewModel, domainModel);`. This will update only the properties that are on your view model (i.e. on your view) and the other properties will be coming from the database. Then simply Save the domain model. – Darin Dimitrov Jul 18 '11 at 14:27
0

If your global.asax gets too big, you can always split the Commands to execute at startup into other classes/methods, and use the Command pattern to invoke them from Global; to include mapping.

We use a separate mapping file for our mappings, and when we want to ignore a property, we use the ignore method on AutoMapper.

Community
  • 1
  • 1
George Stocker
  • 57,289
  • 29
  • 176
  • 237