簡體   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