0

Struggling to get AutoMapper (6.1.1) to work in this scenario of attempting to update an existing Vendor and associated Vendor Contacts.

I've tried using .ignore() and .UseDestinationValues() on the related entities, both to no avail.

Here's what happens to the destination values after the map:

  1. existingStratusVendor.Id = 0 (should be value of existing)
  2. existingStratusVendor.VendorContacts.Id = 0 (should be value of existing)
  3. existingStratusVendor.Items = null, but had 1 related entity prior to mapping, same with all other related virtual properties. (this happens for all other virtual properties that I've marked as .UseDestinationValues() as well)

What am I doing wrong or am I misunderstanding how this is supposed to work?

POCOs

public partial class Vendor
{
    public Vendor()
    {
        this.Items = new HashSet<Item>();
        this.Items1 = new HashSet<Item>();
        this.VendorContacts = new HashSet<VendorContact>();
        this.POHeaders = new HashSet<POHeader>();
        this.ReceiptHeaders = new HashSet<ReceiptHeader>();
        this.ItemPriceCostRules = new HashSet<ItemPriceCostRule>();
    }

    public int Id { get; set; }
    public int CompanyId { get; set; }
    public string VendorName { get; set; }
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string PostalCode { get; set; }
    public string Notes { get; set; }
    public int CreatedById { get; set; }
    public System.DateTime CreatedOn { get; set; }
    public int ModifiedById { get; set; }
    public System.DateTime ModifiedOn { get; set; }
    public string FinancialsId { get; set; }
    public int LeadTimeDays { get; set; }
    public int SafetyStockDays { get; set; }

    public virtual ICollection<Item> Items { get; set; }
    public virtual ICollection<Item> Items1 { get; set; }
    public virtual ICollection<VendorContact> VendorContacts { get; set; }
    public virtual ICollection<POHeader> POHeaders { get; set; }
    public virtual Company Company { get; set; }
    public virtual UserProfile UserProfile { get; set; }
    public virtual UserProfile UserProfile1 { get; set; }
    public virtual ICollection<ReceiptHeader> ReceiptHeaders { get; set; }
    public virtual ICollection<ItemPriceCostRule> ItemPriceCostRules { get; set; }
}

public partial class VendorContact
{
    public int Id { get; set; }
    public int VendorId { get; set; }
    public string ContactName { get; set; }
    public string EmailAddress { get; set; }
    public string OfficePhone { get; set; }
    public string CellPhone { get; set; }
    public int CreatedById { get; set; }
    public System.DateTime CreatedOn { get; set; }
    public int ModifiedById { get; set; }
    public System.DateTime ModifiedOn { get; set; }
    public bool PurchasingContact { get; set; }

    public virtual Vendor Vendor { get; set; }
    public virtual UserProfile UserProfile { get; set; }
    public virtual UserProfile UserProfile1 { get; set; }
}

Maps

CreateMap<Vendor, Vendor>()
    .ForMember(dest => dest.Id, option => option.UseDestinationValue())                  
    .ForMember(dest => dest.Company, option => option.UseDestinationValue())
    .ForMember(dest => dest.POHeaders, option => option.UseDestinationValue())
    .ForMember(dest => dest.ReceiptHeaders, option => option.UseDestinationValue())                
    .ForMember(dest => dest.Items, option => option.UseDestinationValue())
    .ForMember(dest => dest.Items1, option => option.UseDestinationValue())
    .ForMember(dest => dest.ItemPriceCostRules, option => option.UseDestinationValue())
    .ForMember(dest => dest.UserProfile, option => option.UseDestinationValue())
    .ForMember(dest => dest.UserProfile1, option => option.UseDestinationValue())
    ;

CreateMap<VendorContact, VendorContact>()
    .ForMember(dest => dest.Id, option => option.UseDestinationValue())
    .ForMember(dest => dest.VendorId, option => option.UseDestinationValue())
    .ForMember(dest => dest.UserProfile, option => option.UseDestinationValue())
    .ForMember(dest => dest.UserProfile1, option => option.UseDestinationValue())

Code

public ActionConfirmation<int> ImportFromFinancials(Vendor financialsModifiedVendor, int intUserId)
{    
Vendor vendorToUpdate;

var existingStratusVendor = _vendorRepository
    .SearchFor(a => a.CompanyId == intCompanyId && a.FinancialsId == financialsModifiedVendor.FinancialsId).FirstOrDefault();

if (existingStratusVendor == null) //add a new vendor
{
    vendorToUpdate = financialsModifiedVendor;
}
else
{    
    Mapper.Map(financialsModifiedVendor, existingStratusVendor);   
    vendorToUpdate = existingStratusVendor;
}

//Save Vendor
var baseAppServ = new BaseAppServ<Vendor>(_repository);
var vendorUpdateResult = baseAppServ.SaveOrUpdate(vendorToUpdate, intUserId);

if (!vendorUpdateResult.WasSuccessful) return vendorUpdateResult;
...
}
crichavin
  • 4,672
  • 10
  • 50
  • 95

1 Answers1

0

both entities has the same name, it looks like you are missing a namespace

CreateMap<Other.Namespace.VendorContact, VendorContact>()
.ForMember(dest => dest.Id, option => option.UseDestinationValue())
.ForMember(dest => dest.VendorId, option => option.UseDestinationValue())
.ForMember(dest => dest.UserProfile, option => option.UseDestinationValue())
.ForMember(dest => dest.UserProfile1, option => option.UseDestinationValue())
Daniel Rapaport
  • 375
  • 2
  • 18
  • Yes they do. It is a mapping of the same class to itself. We ate not using a new DTO type class to map from, we read in a vendor contact from an external API as a type VendorContact, then search for an existing VendorContact in our internal database and then attempt to use this map to update the existing VendorContact with the one retreived from the API. Can you not map an object to another object instance of the same class? – crichavin Jun 27 '18 at 20:23