繁体   English   中英

FetchXML查询问题

[英]FetchXML query issue

我有一个名为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);
                }

            }

但是,当我调用无效的插件执行异常以查看查询返回的内容时,变量“ costToBusiness”仅保存“ Microsoft.Xrm.Sdk.Money”,而不保存记录中的实际值。

有人知道我做错了吗?

我很确定您需要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();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM