0

I've found two solution to ignore non mapped properties but one of them also ignore the conventional mappings, and the second doesn't work with QueryableExtensions to return an IQueryable (don't know why but I get the error Argument types do not match).

Does anyone has a solution to ignore non mapped properties that covers both aspects above?

Community
  • 1
  • 1
Joao Leme
  • 9,598
  • 3
  • 33
  • 47
  • Just informational comment, does IQueryable work with other AutoMapper maps? Wouldn't you want to "realize" the results of IQueryable and not attempt to copy to a DTO? Mapping something to IQueryable does not seem like what you want to do as your DTO's usually cross a process boundary or are served up as JSON. – CodeMonkeyKing Apr 20 '13 at 19:48
  • What version of AutoMapper are you using and what type of IQueryable expression are you mapping? LINQ to SQL, LINQ to EF, other? – CodeMonkeyKing Apr 20 '13 at 20:13
  • @CodeMonkeyKing I already updated earlier today to the latest 2.2.1 after reading (https://github.com/AutoMapper/AutoMapper/issues/163) but with no luck (still same error). IQueryable works fine with other maps, including using the "IgnoreAllUnmapped" map. I don't want to "realize" IQueryable otherwise it would bring a bunch of unnecessary data since I'll be calling from GetAll() or Table() in the repository. – Joao Leme Apr 20 '13 at 20:22
  • I rolled back my test bed to 2.1.262 to attempt to duplicate your problem and see if I can get the IgnoreAllNonExisting to work. – CodeMonkeyKing Apr 20 '13 at 20:30
  • This is the only advice I have for you: try making use of the CanResolveValue() inside of the loop over the unmapped property names: `if (existingMaps.GetPropertyMaps().Any(pm => pm.CanResolveValue() && pm.SourceMember.Name == property)) { expression.ForMember(property, opt => opt.Ignore()); }` – CodeMonkeyKing Apr 20 '13 at 23:07
  • @CodeMonkeyKing no luck – Joao Leme Apr 21 '13 at 00:42
  • At a loss without a simple test case to help you. I've not been able to duplicate what you are experiencing. – CodeMonkeyKing Apr 21 '13 at 16:54

3 Answers3

3

When using QueryableExtensions you have to be explicit with some type conversions, such as int? to int. This is probably the source of the "Argument types do not match" exception.

If you have many properties that need a type conversion -- like if you had many other properties where you find you are doing c.MyVariable ?? 0 -- you can instead define a conversion rule and not have to be explicit about every property.

Normally, to do type conversions in Automapper, you would use ConvertUsing but when using QueryableExtensions, you need to instead use ProjectUsing.

You could use the following line and it will take care of all mappings from int? to int without the need to explicitly specify the mappings for each property:

cfg.CreateMap<int?, int>().ProjectUsing(src => src.HasValue ? src.Value : 0);
Brad Rem
  • 6,036
  • 2
  • 25
  • 50
2

Chaining at the end of the mapping with the .ForAllOtherMembers(opt => opt.Ignore()); worked for me. This should be the last method in the method chain.

Sreehari
  • 49
  • 8
1

Problem solved. It was in this line of code

.ForMember(p => p.Gender, opt => opt.MapFrom(c => c.GenderCode))

where p.Gender was of type int and GenderCode of type int?. so changing to

.ForMember(p => p.Gender, opt => opt.MapFrom(c => c.GenderCode ?? 0))

fixed the problem. What made it hard to troubleshoot is that the mapping code above was working until I try to return IQueryable.

Joao Leme
  • 9,598
  • 3
  • 33
  • 47