0

I am new to automapper. I am trying to map an object to a DTO. The object has a locationId which is nullable. I need to either assign empty string to the DTO's "LocationName" property if locationId is null OR select the locationName from a table in SQL using EF. How do I accomplish this?

The classes:

public class Foo
{
        public int id { get; set; } //not relevant, here for convention
        public int? LocationId { get; set; } 
}

public class FooDto
{
        public int id { get; set; } //not relevant, here for convention
        public string LocationName { get; set; }
}

My attempt:

Mapper.CreateMap<Foo, FooDto>()
    .ForMember( dest => dest.locationName, options => options.ResolveUsing(src=> src.LocationId == null ? "" : src => db.Locations.SingleOrDefault(l => l.Id == src.LocationId).Name) )

I used this as an example, but it's not using EF, so I have no idea what I am doing wrong. I never did get a clear answer on MapFrom vs ResolveUsing either from various sources such as this.

Community
  • 1
  • 1
VSO
  • 11,546
  • 25
  • 99
  • 187
  • Where is `db` defined? Is `Foo` an EF entity? – Matthew Jul 12 '15 at 02:57
  • db is ApiContext, automapper has access to it. Yes, Foo is an EF entity. It's in scope. Just as a side note - the db access part is not something I am worried about/don't know how to do. Whatever I am doing wrong, I am doing it wrong with automapper. I have no problems selecting data from db. – VSO Jul 12 '15 at 03:01
  • One option may be to change `Foo.LocationId` to just `Foo.Location`, then AutoMapper would be able to map `LocationName` using the default mapping convention. The caveat would be is that when mapping it must happen within a context. – Matthew Jul 12 '15 at 03:13
  • I don't understand what difference that would make. That sentence kind of sounds like me being rude, but I don't mean it that way. – VSO Jul 12 '15 at 03:16
  • 1
    The difference is that you would not need to configure AutoMapper to be aware of EF, and instead you would leverage EF's property navigation to get the values. When using ORMs I tend to avoid having foreign key ID properties and instead use navigational properties. A lot of this is personal preference, so take it with a grain of salt. – Matthew Jul 12 '15 at 03:29
  • Oh, I got you now, ty. – VSO Jul 12 '15 at 03:30
  • +1 for navigation properties. You really want to map from Foo.Location.Id and Foo.Location.Name. In the latter case, you wouldn't need MapFrom or ResolveUsing, you'd just have something called "LocationName". – Jimmy Bogard Jul 13 '15 at 15:58

1 Answers1

0

My concern was the fact that I am mapping one property type to another and using EF. The fact is that automapper does not care. This code works:

Mapper.CreateMap<Foo, FooDto>()
    .ForMember( dest => dest.locationName, opt => opt.ResolveUsing(src=> src.LocationId == null ? "" : db.Locations.SingleOrDefault(l => l.Id == src.LocationId).Name) )

I was overthinking it, when the issue was in my lambda expression. I passed the argument twice because I wasn't thinking about it.

VSO
  • 11,546
  • 25
  • 99
  • 187