DynamicsCRM+如何在插件代码中动态获取基于类型的属性值



我有以下要求。

我需要在同一实体的多个记录中执行每个字段的求和。然而,在执行求和时,我还需要检查类型并强制转换它们。例如,For整数强制转换为Int,For Decimal强制转换为Decimal。还有一些值也是别名值。我正在寻找一个通用函数,我可以为别名字段和直接字段调用它,它会根据类型返回值

写在下面的代码的背景-

  • 属性列表是属于实体

AttributeList-中存储字段值的格式

AttributeList = { "price ",  "quantity", "contact.revenue", "opportunity.sales"}
  • 价格、数量-我们查询的主要实体的字段

  • contact.revention、opportunity.sales-别名实体的字段,实体名称被附加以了解它是哪个实体的字段

下面是我迄今为止尝试过的代码-

我的attributeList中只有十进制和整数字段。

private void calculate(List<string> attributeList,List<Entity> mainEntityList,Guid targetId,Guid oppId,Guid contactId)
{
var mainentity = new mainEntity();
mainentity.Id = targetId;
var opportunity = new Opportunity();
opportunity.Id = oppId;
var contact = new Contact();
contact.Id = contactId;

foreach (var attribute in attributeList)
{
var fieldSum = new decimal(0);
int intFieldSum = 0;
bool attributeFound = false;
foreach (var entity in mainEntityList)
{

if (entity.Contains(attribute))
{
var type = entity[attribute].GetType().Name;
attributeFound = true;
switch (type)
{
case "AliasedValue":
var aliasedFieldValue = entity.GetAttributeValue<AliasedValue>(attribute);
if (aliasedFieldValue.Value.GetType().Name == "Decimal")
{
decimalFieldSum += (decimal)aliasedFieldValue.Value;
}
else
{
intFieldSum += (int)aliasedFieldValue.Value;
}
break;
case "Decimal":
decimalFieldSum += entity.GetAttributeValue<decimal>(attribute);
break;
case "Int32":
intFieldSum += entity.GetAttributeValue<int>(attribute);
break;
default:
break;
}
}
}
if (attributeFound)
{
if (attribute.Contains("opportunity"))
{
opportunity[attribute] =  decimalFieldSum != 0 ? decimalFieldSum : intFieldSum; 
}
else if (attribute.Contains("contact"))
{
contact[attribute] = decimalFieldSum != 0 ? decimalFieldSum : intFieldSum; 
}
else
{
mainentity[attribute] = decimalFieldSum != 0 ? decimalFieldSum : intFieldSum; 
}
}
}
service.update(opportunity);
service.update(contact);
service.update(mainentity);
}

如有任何帮助,我们将不胜感激。

只需稍微编辑一下代码。

var fieldSum = new decimal(0);
foreach (var entity in mainEntityList)
{
fieldSum += GetAttrValue(entity, attribute);
}

您可以使用此函数来计算十进制类型的fieldSum变量。

private decimal GetAttrValue(Entity entity, string attribute)
{
var attrValue = new decimal(0);

if (!entity.Contains(attribute) || entity.Attributes[attribute] == null)
{
return attrValue;
}

var type = entity.Attributes[attribute].GetType().Name;
switch (type)
{
case "AliasedValue":
var aliasedFieldValue = entity.GetAttributeValue<AliasedValue>(attribute);
attrValue = type == "Decimal" ? (decimal)aliasedFieldValue.Value : (int)aliasedFieldValue.Value;
break;
case "Decimal":
attrValue = entity.GetAttributeValue<decimal>(attribute);
break;
case "Int32":
attrValue = entity.GetAttributeValue<int>(attribute);
break;
default:
break;
}
return attrValue;
}

另一方面,如果您只需要一个为属性返回十进制或int值的通用函数,则可以使用此

private T GetAttrValue<T>(Entity entity, string attribute)
{
if (!entity.Contains(attribute) || entity.Attributes[attribute] == null)
{
return default(T);
}
T result;
var type = entity.Attributes[attribute].GetType().Name;
if (type == "AliasedValue")
{
var aliasedFieldValue = entity.GetAttributeValue<AliasedValue>(attribute);
result = (T)aliasedFieldValue.Value;
}
else
{
result = entity.GetAttributeValue<T>(attribute);
}
return result;
}

--Update-
所以,如果我理解您的要求,这里是整个代码
首先添加此类。

public class AttributeInfo
{
public string Name { get; set; }
public Type Type { get; set; }
public decimal DecimalSum { get; set; } = new decimal(0);
public int IntSum { get; set; } = 0;
}

并添加此功能

private void SetValue(Entity entity, AttributeInfo attributeInfo)
{
if (entity.Contains(attributeInfo.Name))
{
switch (attributeInfo.Type.Name)
{
case "Decimal":
entity[attributeInfo.Name] = attributeInfo.DecimalSum;
break;
case "Int32":
entity[attributeInfo.Name] = attributeInfo.IntSum;
break;
default:
break;
}
}
}

那么这就是你的Calculate功能

private void Calculate(List<string> attributeList, List<Entity> mainEntityList, Guid targetId, Guid oppId, Guid contactId)
{
var mainentity = new mainEntity();
mainentity.Id = targetId;
var opportunity = new Opportunity();
opportunity.Id = oppId;
var contact = new Contact();
contact.Id = contactId;
var attributesInfo = new List<AttributeInfo>();
foreach (var attribute in attributeList)
{
var attributeInfo = new AttributeInfo
{
Name = attribute
};
foreach (var entity in mainEntityList)
{
if (entity.Contains(attribute))
{
attributeInfo.Type = entity[attribute].GetType();
switch (attributeInfo.Type.Name)
{
case "AliasedValue":
var aliasedFieldValue = entity.GetAttributeValue<AliasedValue>(attribute);
if (aliasedFieldValue.Value.GetType().Name == "Decimal")
{
attributeInfo.DecimalSum += (decimal)aliasedFieldValue.Value;
}
else
{
attributeInfo.IntSum += (int)aliasedFieldValue.Value;
}
break;
case "Decimal":
attributeInfo.DecimalSum += entity.GetAttributeValue<decimal>(attribute);
break;
case "Int32":
attributeInfo.IntSum += entity.GetAttributeValue<int>(attribute);
break;
default:
break;
}
}
}
attributesInfo.Add(attributeInfo);
}
foreach (var attributeInfo in attributesInfo)
{
if (attributeInfo.Type != null)
{
SetValue(mainentity, attributeInfo);
SetValue(opportunity, attributeInfo);
SetValue(contact, attributeInfo);
}
}
service.update(mainentity);
service.update(opportunity);
service.update(contact);
}

我应该说calculate函数的结构对我来说仍然很奇怪。然而,在这里我试图保持主要结构。

最新更新