3
votes

I have the following method for retrieving entity from Dynamics:

private Entity GetEntity(CrmOrganizationServiceContext context, string id, string entityLogicalName, params string[] columnSet)
{
    Guid guid;
    if (!Guid.TryParse(id, out guid))
    {
        return null;
    }

    if (columnSet != null && columnSet.Any())
    {
        return context.Retrieve(entityLogicalName, guid, new ColumnSet(columnSet));
    }

    return context.Retrieve(entityLogicalName, guid, new ColumnSet(allColumns: true));
}

I try to retrieve invoicedetail entity and update its attributes. The method for updating attributes looks like this:

public void UpdateAttributes(Entity entity, EntityDto entityDto)
{
    foreach (var attribute in entityDto.Attributes)
    {
        entity[attribute.Key] = attribute.Value;
    }
}

And the Update method:

public void Update(CrmOrganizationServiceContext context, IEnumerable<EntityDto> entities)
{
    foreach (var entityDto in entities)
    {
        var entity = GetEntity(context, entityDto.CrmId.ExternalId, entityDto.TypeName, entityDto.Attributes.Keys.ToArray());
        if (entity != null)
        {
            _entityService.UpdateAttributes(entity, entityDto);
            context.Attach(entity);
            context.UpdateObject(entity);
            context.Update(entity);
        }

        context.SaveChanges();
    }
}

I noticed that for the invoice entity this method works, but when I try to retrieve invoicedetail (it is reference to invoice entity) and update the attributes with method above I'm getting three additional attributes in my entity from nowhere (all of them are entity references) and when I try to update it, I'm getting the exception:

System.ServiceModel.FaultException`1: 'System.InvalidCastException: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #635D1534'

The invoicedetail entity attributes

Entity attributes that I want to update

As I read on MSDN, updating invoicedetail entities is supported. How can I solve the problem with this exception and update the invoicedetail entity in Dynamics?

UPDATE 21.06.2017

After few days research I noticed that if I delete the priceperunit attribute from my data set for invoicedetail entity, everything works ok. I can create new entity in Dynamics with priceperunit but I can not update it in the same way.

entity["priceperunit"] = 999.0;

The type of this field in Dynamics is Currency (as I can see, it is not entity reference), so I guess when I try to update this value, Dynamics casts decimal to Currency (or something like that). Does anyone know how to update that kind of values?

2
Please show the code for the _entityService.UpdateAttributes method. That is likely where something is causing a bad datatype.Nicknow

2 Answers

4
votes

Do you know that your entity references are actually EntityReference objects in this line:

entity[attribute.Key] = attribute.Value;  

Perhaps they're Entity or EntityDto objects, in which case you'll get an InvalidCastException.

If you're not sure, and unable to debug, you could type check them and instantiate an EntityReference:

foreach (var attribute in entityDto.Attributes)
{
    if (attribute.Value is Entity)
    {                                    
        entity[attribute.Key] = new EntityReference(((Entity)attribute.Value).LogicalName, ((Entity)attribute.Value).Id);
    }
    // Check if EntityDto...
}
1
votes

You cannot use entity[attribute.Key] = attribute.Value; for all datatypes.

Invoice & InvoiceDetail are possessing parent/child relationships, so Parent Invoice Id will be available as Entityreference (lookup) in Detail entity.

You have to check the datatype of each attribute & do the mapping inside foreach loop of Attributes.

entity[attribute.Key] = attribute.Value.ToEntityReference();

or

entity[attribute.Key] = new EntityReference("entity_name",Id);