Dynamics CRM C#SDK - 尝试获取Quote Line的名称,但字段不存在?
我想列出报价的报价行,同时保持通用接口足够通用,以便能够类似地显示其他实体。Dynamics CRM C#SDK - 尝试获取Quote Line的名称,但字段不存在?
为了做到这一点,我试图使用EntityMetadata中的PrimaryNameAttribute。适用于大多数实体,但对于QuoteDetail,PrimaryNameAttribute是“productidname” - 实际上并不作为QuoteDetail实体的一部分存在的属性。
此字段“productidname”也是其他实体(OpportunityProduct,SalesOrderDetail)的PrimaryNameAttribute,在这些情况下该字段也缺失。
什么给?我觉得我已经搜索了所有的谷歌,似乎没有人遇到过这个问题,所以,也许我错过了一些简单的东西。
这是MSDN的QuoteDetail实体页面,显示了我在说的内容:https://msdn.microsoft.com/en-us/library/mt607959.aspx请注意,PrimaryNameAttribute未在页面的任何其他位置列出。
QuoteDetail(喜欢的SalesOrderDetail和OpportunityProduct)是特殊的,因为它可以是关系实体的目录产品项目或写在项目,无论从productidname
(产品目录从)或productdescription
得到它的“名”(直写在产品中)。您需要加入相关产品以获取其名称。
如果您即将开发通用解决方案/接口,这是您需要解决的每个查找属性的问题。
如果你永远只能从连接在查找记录需要的PrimaryNameAttribute,您可以从FormattedValues
收集你的“主”实体检索名称:
string productname = quotedetail.FormattedValues["productid"];
但更好/更安全:
string productname;
quotedetail.FormattedValues.TryGetValue("productid", out productname);
处理任意实体的属性可能如下所示:
foreach (var key in record.Attributes.Keys)
{
if (record.FormattedValues.ContainsKey(key))
{
string formattedvalue;
if (record.FormattedValues.TryGetValue(key, out formattedvalue))
{
Console.WriteLine(formattedvalue); // use formattedvalue string
}
continue; // skip to next field when found in formatted values
}
object attributevalue;
record.Attributes.TryGetValue(key, out attributevalue);
object actualvalue;
string actualtext = string.Empty;
// handle AliasedValue fields from JOINed/LinkEntities
if (attributevalue.GetType().Name == "AliasedValue")
{
actualvalue = ((AliasedValue)attributevalue).Value;
}
else
{
actualvalue = attributevalue;
}
switch (actualvalue.GetType().Name)
{
case "EntityReference":
actualtext = ((EntityReference)actualvalue).Name; // this will catch Lookup values not contained in FormattedValues when you just created them
break;
case "DateTime":
actualtext = string.Format("{0:dd.MM.yyyy}", ((DateTime)actualvalue).ToLocalTime()); // ... any other dateTime format you'd like
break;
case "Guid":
actualtext = string.Format("{0:D}", actualvalue); // Entity Primary key
break;
default:
actualtext = (string)actualvalue; // anything else
break;
}
Console.WriteLine(actualtext);
}
您仍然需要照顾新分配的OptionSetValue
和Money
属性(类似于EntityReference
),因为这些属性通常会从FormattedValues
中提取。
由于本示例处理的是现有的crm数据,因此您需要了解您的实体可能不包含所有属性的缺陷,因此您可能需要重复执行.Attributes.Keys
的预定义属性名称集合。
我的个人策略通常是创建一个轻量级ORM来在类型化对象和CRM实体之间进行映射,但这不符合您对通用接口的要求。
对于像你这样的情况下,它是非此即彼的属性,我把语法糖的工作:
string pn = qd.GetAttributeValue<string>("productdesription") ?? (qd.GetAttributeValue<EntityReference>("productid") ?? new EntityReference { Name = string.Empty }).Name;
尝试获得写在产品名称;如果它为空,尝试获取Lookup名称,如果它为null,则从假EntityReference中获取一个空字符串。
这允许无摩擦的编码,很好地解决了“这个或那个属性”。
好的,谢谢。元数据中是否有可以指导我的代码根据需要引入相关实体/字段的内容?或者这是我需要硬编码到我的解决方案,以涵盖违规实体? – Yoni
刚刚看到您的更新。很快就会尝试。再次感谢。 – Yoni
更新示例应该给你一个总体思路。我将添加完整的代码示例,介绍如何随后提取任意属性。 – Filburt