首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >FetchXML查询问题

FetchXML查询问题
EN

Stack Overflow用户
提问于 2014-07-28 18:34:16
回答 1查看 3.4K关注 0票数 0

我有一个名为Issue的自定义实体,它有一个链接到实体Cost to Business的网格,用户可以将从Cost到Business的记录添加到问题记录。我希望从网格中的项目自动填充业务的总体成本字段。我使用了一个插件来为我自己做这件事。在插件中,我构造了以下FetchXML查询来检索我的数据

代码语言:javascript
复制
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”,而不是记录中的实际值。

有人知道我做错了什么吗?

EN

回答 1

Stack Overflow用户

发布于 2014-07-29 01:40:05

我很确定你需要一个Value.Value。

代码语言:javascript
复制
((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()

我假设这是经过大量编辑的代码,因为您循环遍历所有代码,但只吐出最后一段代码。

使用别名值有点糟糕,所以我在内部使用了这些扩展方法:

代码语言:javascript
复制
/// <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;
}

这会将您的代码更改为:

代码语言:javascript
复制
_entity.GetAliasedValue<Money>("new_costtobusiness").ToString();
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24993356

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档