更新动态发票明细实体时出现InvalidCastException

时间:2017-06-09 09:50:55

标签: c# .net dynamics-crm microsoft-dynamics

我有以下方法从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));
}

我尝试检索invoicedetail实体并更新其属性。更新属性的方法如下所示:

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

更新方法:

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();
    }
}

我注意到,对于发票实体,此方法有效,但当我尝试检索invoicedetail(它是对发票实体的引用)并使用上面的方法更新属性时,我在我的实体中从无处获得三个附加属性(所有这些都是实体引用)当我尝试更新它时,我得到了例外:

  

System.ServiceModel.FaultException`1:&#39; System.InvalidCastException:Microsoft Dynamics CRM遇到错误。管理员或支持的参考编号:#635D1534&#39;

The invoicedetail entity attributes

Entity attributes that I want to update

正如我在MSDN上阅读的那样,支持更新invoicedetail实体。如何解决此异常的问题并更新Dynamics?中的invoicedetail实体?

更新21.06.2017

经过几天的研究,我注意到如果我从invoicedetail实体的数据集中删除priceperunit属性,一切正常。我可以使用priceperunit在Dynamics中创建新实体,但我无法以相同的方式更新它。

entity["priceperunit"] = 999.0;

Dynamics中此字段的类型是货币(我可以看到,它不是实体引用),所以我想当我尝试更新此值时,Dynamics会将十进制转换为货币(或类似的东西)。有谁知道如何更新这种价值观?

2 个答案:

答案 0 :(得分:4)

您是否知道您的实体引用实际上是此行中的EntityReference个对象:

entity[attribute.Key] = attribute.Value;  

也许他们是EntityEntityDto个对象,在这种情况下,您将获得InvalidCastException

如果您不确定并且无法调试,可以键入检查它们并实例化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 :(得分:1)

您不能将entity[attribute.Key] = attribute.Value;用于所有数据类型。

发票&amp; InvoiceDetail拥有父/子关系,因此Parent Invoice Id将在Detail实体中作为Entityreference(lookup)提供。

您必须检查每个属性的数据类型&amp;在属性的foreach循环中进行映射。

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

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