Question

I'm mapping data using Automapper in my ASP.NET MVC4 Application's from my domain model onto my view model.
On my development machine with the integrated IIS this works perfectly, however when deploying it to the real IIS, suddenly my code only maps the data seemingly on arbitrary occasions.
It seems that the mapping works once after redeploying the application and sometimes after attaching the remote debugger.

My code is:

iPXE dbCon = new iPXE();
Models.Device bootDevice = dbCon.Devices.SingleOrDefault(d => d.serial == serial);
var imagePredicate = PredicateBuilder.False<Models.Image>();
imagePredicate = imagePredicate.Or(d => d.anyboot == true); // Images everyone can boot
if (bootDevice != null) // If the boot device is in the database
{
    imagePredicate = imagePredicate.Or(d => d.Devices.Any(e => e.id == bootDevice.id)); // Retrieve all images assigned to the device
}
IEnumerable<Models.Image> allowedImages = dbCon.Images.AsExpandable().Where(imagePredicate);

Mapper.CreateMap<Models.Category, Category>()
    .ForMember(x => x.name, opt => opt.MapFrom(src => src.CategoryTranslations.SingleOrDefault(d => d.locale == locale) == null || // Either no translation row found
                                                      src.CategoryTranslations.SingleOrDefault(d => d.locale == locale).name != null ? // Or specific value is null
                                                      src.name : // Then use name from main table (untranslated)
                                                      src.CategoryTranslations.SingleOrDefault(d => d.locale == locale).name)) // Otherwise use translated value
    .ForMember(x => x.images, opt => opt.MapFrom(src => allowedImages.Intersect(src.Images)));
Mapper.CreateMap<Models.Image, Image>()
    .ForMember(x => x.description, opt => opt.MapFrom(src => src.ImageTranslations.SingleOrDefault(d => d.locale == locale) == null ||
                                                             src.ImageTranslations.SingleOrDefault(d => d.locale == locale).description == null ? 
                                                             src.description : 
                                                             src.ImageTranslations.SingleOrDefault(d => d.locale == locale).description))
    .ForMember(x => x.code, opt => opt.MapFrom(src => src.ImageTranslations.SingleOrDefault(d => d.locale == locale) == null ||
                                                      src.ImageTranslations.SingleOrDefault(d => d.locale == locale).code == null ? 
                                                      src.code : 
                                                      src.ImageTranslations.SingleOrDefault(d => d.locale == locale).code));

categories = Mapper.Map<IEnumerable<Models.Category>, List<Category>>(allowedImages.Select(c => c.Category1).Distinct());

public class Category
{
    public string name { get; set; }
    public List<Image> images { get; set; }
}

public class Image
{
    public string tag { get; set; }
    public string description { get; set; }
    public string code { get; set; }
}

What I'm doing is basically getting a device from the database, getting all assigned images for the device (N:M) and then creating Automapper-Maps for categories and images that belong to the device.

The exact problem is that on the productive server, the images-Lists of the category objects stay empty, even though there is data in allowedImages (5 images), bootDevice (the device data) and allowedImages.Select(c => c.Category1).Distinct() (2 categories).

I'm using the same SQL server for both my machine and the server. If you need any more information, please feel free to ask.

Était-ce utile?

La solution

You are calling 'CreateMap' each time the method runs. As I understand, you should only do this once within your application domain. Try moving the CreateMap logic to where it gets called from Application_OnStart to see if that gives you more consistent behavior.

Also, the line:

.ForMember(x => x.images, opt => opt.MapFrom(src => allowedImages.Intersect(src.Images)));

may be troubling you. You may need to change that to an AfterMap that calls a static method that performs the Intersect on your source & destination collections.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top