我有一个名为Issue的自定义实体,其网格链接到实体Cost To Business,用户可以将Cost To Business中的记录添加到问题记录中。我希望从网格中的项目自动填充业务领域的总体成本。我已经使用插件为我做了这个。在插件中,我构建了以下FetchXML查询来检索我的数据
string fetchxml =
@"<fetch distinct='true' mapping='logical' output-format='xml-platform' version='1.0'>
<entity name='new_issue'>
<attribute name='new_issueid'/>
<attribute name='new_name'/>
<attribute name='createdon'/>
<order descending='false' attribute='new_issueid'/>
<link-entity name='new_costtobusiness' alias='ab' to='new_issueid' from='new_issue_costid'>
<attribute name='new_costtobusiness'/>
</link-entity>
</entity>
</fetch>";
EntityCollection result = service.RetrieveMultiple(new FetchExpression(fetchxml));
{
if (result != null && result.Entities.Count > 0)
{
List<string> _product = new List<string>();
foreach (Entity _entity in result.Entities)//loop through every record
{
costToBusiness = ((AliasedValue)_entity.Attributes["ab.new_costtobusiness"]).Value.ToString();
}
throw new InvalidPluginExecutionException(costToBusiness);
}
}
但是,当我调用Invalid Plugin Execution Exception时,查看查询返回的变量&#34; costToBusiness&#34;只持有&#34; Microsoft.Xrm.Sdk.Money&#34;而不是记录中的实际值。
有谁知道我做错了什么?
答案 0 :(得分:1)
我很确定你需要一个Value.Value。
((AliasedValue)_entity.Attributes["ab.new_costtobusiness"]) // Returns an AliasedValue
.Value // Returns a Money but is actually an Object
.ToString() // Calls the default ToString of Money which is just spit out the type name.
// This should be correct:
((Money)((AliasedValue)_entity.Attributes["ab.new_costtobusiness"]).Value).Value.ToString()
我假设这是经过大量编辑的代码,因为你遍历所有代码,但只吐了最后一个。
使用别名值很糟糕,所以我在内部使用这些扩展方法:
/// <summary>
/// Returns the Aliased Value for a column specified in a Linked entity
/// </summary>
/// <typeparam name="T">The type of the aliased attribute form the linked entity</typeparam>
/// <param name="entity"></param>
/// <param name="attributeName">The aliased attribute from the linked entity. Can be preappeneded with the
/// linked entities logical name and a period. ie "Contact.LastName"</param>
/// <returns></returns>
public static T GetAliasedValue<T>(this Entity entity, string attributeName)
{
string aliasedEntityName = SplitAliasedAttributeEntityName(ref attributeName);
foreach (var entry in entity.Attributes)
{
if (entity.IsSpecifiedAliasedValue(entry, aliasedEntityName, attributeName))
{
var aliased = entry.Value as AliasedValue;
if (aliased == null) { throw new InvalidCastException(); }
try
{
// If the primary key of an entity is returned, it is returned as a Guid. If it is a FK, it is returned as an Entity Reference
// Handle that here
if (typeof (T) == typeof (EntityReference) && aliased.Value is Guid)
{
return (T)(object) new EntityReference(aliased.EntityLogicalName, (Guid) aliased.Value);
}
if(typeof (T) == typeof (Guid) && aliased.Value is EntityReference)
{
return (T)(object) ((EntityReference)aliased.Value).Id;
}
return (T)aliased.Value;
}
catch (InvalidCastException)
{
throw new InvalidCastException(
String.Format("Unable to cast attribute {0}.{1} from type {2} to type {3}",
aliased.EntityLogicalName, aliased.AttributeLogicalName,
aliased.Value.GetType().Name, typeof(T).Name));
}
}
}
throw new Exception("Aliased value with attribute " + attributeName +
" was not found! Only these attributes were found: " + String.Join(", ", entity.Attributes.Keys));
}
/// <summary>
/// Handles spliting the attributeName if it is formated as "EntityAliasedName.AttributeName",
/// updating the attribute name and returning the aliased EntityName
/// </summary>
/// <param name="attributeName"></param>
private static string SplitAliasedAttributeEntityName(ref string attributeName)
{
string aliasedEntityName = null;
if (attributeName.Contains('.'))
{
var split = attributeName.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
if (split.Length != 2)
{
throw new Exception("Attribute Name was specified for an Alaised Value with " + split.Length +
" split parts, and two were expected. Attribute Name = " + attributeName);
}
aliasedEntityName = split[0];
attributeName = split[1];
}
return aliasedEntityName;
}
private static bool IsSpecifiedAliasedValue(this Entity entity, KeyValuePair<string,object> entry, string aliasedEntityName, string attributeName)
{
AliasedValue aliased = entry.Value as AliasedValue;
if (aliased == null)
{
return false;
}
// There are two ways to define an Aliased name that need to be handled
// 1. At the Entity level in Query Expression or Fetch Xml. This makes the key in the format AliasedEntityName.AttributeName
// 2. At the attribute level in FetchXml Group. This makes the key the Attribute Name. The aliased Entity Name should always be null in this case
bool value = false;
if (aliasedEntityName == null)
{
// No aliased entity name specified. If attribute name matches, assume it's correct, or,
// if the key is the attribute name. This covers the 2nd possibility above
value = aliased.AttributeLogicalName == attributeName || entry.Key == attributeName;
}
else if (aliased.AttributeLogicalName == attributeName)
{
// The Aliased Entity Name has been defined. Check to see if the attribute name join is valid
value = entry.Key == aliasedEntityName + "." + attributeName;
}
return value;
}
这会将您的代码更改为:
_entity.GetAliasedValue<Money>("new_costtobusiness").ToString();