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