2

ユーザーが CRM ルックアップを実行できるようにする、CRM の外部の Web ページがあります。通常の CRM UI と同様に、クイック検索を使用して検索結果をフィルタリングする実装を実装する必要があります。

選択したエンティティ/ビューの FetchXML を取得し、選択したエンティティのクイック検索ビューの FetchXML を取得し、isquickfindfields=1 のフィルター ノードを抽出し、{0} を検索ボックスに入力したものに置き換え、変更したノードを選択したビューの FetchXML を呼び出して実行します。

私が直面している問題は、クイック検索フィルターの一部が関連エンティティの id フィールドに対して行われていることですが、一致はそのエンティティのプライマリ名属性に対して行う必要があります。

たとえば、アカウント エンティティのクイック検索は次のとおりです。

<fetch version="1.0" output-format="xml-platform" mapping="logical">
<entity name="account">
    <attribute name="name" />
    <attribute name="primarycontactid" />
    <attribute name="address1_city" />
    <attribute name="telephone1" />
    <attribute name="emailaddress1" />
    <order attribute="name" descending="false" />
    <filter type="and">
        <condition attribute="statecode" operator="eq" value="0" />
    </filter>
    <filter type="or" isquickfindfields="1">
        <condition attribute="primarycontactid" operator="like" value="{0}" />
        <condition attribute="telephone1" operator="like" value="{0}" />
        <condition attribute="emailaddress1" operator="like" value="{0}" />
        <condition attribute="accountnumber" operator="like" value="{0}" />
        <condition attribute="name" operator="like" value="{0}" />
    </filter>
    <attribute name="accountid" />
</entity>

検索テキストを挿入してビューを実行すると、RetrieveMultiple から次のエラーが発生します。

An exception System.FormatException was thrown while trying to convert input value '%acme%' to attribute 'account.primarycontactid'. Expected type of attribute value: System.Guid. Exception raised: Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).

通常の CRM インターフェースを使用し、アカウントに対して検索を行い、クイック検索ボックスに連絡先の名前を入力すると、検索は期待どおりに機能します (主な連絡先の名前が入力したものであるアカウントが一覧表示されます)。このため、CRM がデータベースにクエリを実行すると、エンティティ参照のプライマリ名属性に対して非 Guid 文字列が "インテリジェントに" 照合されると想定していました。

クイックサーチ フィルターを追加するコード ブロック (メソッド全体の pastebin ) は次のとおりです

if (string.IsNullOrWhiteSpace(searchString) == false)
{
    var quickSearch = CRMCache.SavedQueries.FirstOrDefault(q => q.ReturnedTypeCode == view.ReturnedTypeCode && q.QueryType == SavedQueryQueryType.QuickFindSearch);
    if (quickSearch != null)
    {
        var quickSearchXml = XElement.Parse(quickSearch.FetchXml);
        var quickSearchFilter = quickSearchXml.XPathSelectElement("//filter[@isquickfindfields=1]");
        foreach (var condition in quickSearchFilter.Elements("condition"))
        {
            condition.SetAttributeValue("value", string.Format(condition.Attribute("value").Value, "%" + searchString + "%"));
        }

        viewEntityNode.Add(quickSearchFilter);
    }
}

通常の CRM UI がこれをどのように処理するのか興味がありますが、私の質問は、関連するエンティティのプライマリ名属性に対して正しくフィルター処理するルックアップ/ビューにクイック検索フィルター処理を動的に適用するにはどうすればよいですか?


[明確化のために編集]

クイック検索(またはクイック検索) は、CRM のビュー タイプの 1 つです。ユーザーがクイック検索ボックスにテキストを入力するとき、またはルックアップをフィルタリングするときに、どの属性が検索されるかを定義します。すべてのエンティティにはクイック検索ビューがあり、エンティティは 1 つのみを持つことができます。

関連するエンティティの名前と一致するという要件は、クイック検索ビューに由来します。それらのすべてにエンティティ参照のフィルターが含まれているわけではありませんが、含まれている場合は、GUID ではなく名前と照合する必要があります。クイック検索ビューの FetchXML には id に対するフィルターがありますが、通常の CRM UI は関連するエンティティの名前に対して検索文字列を正しく適用するため、CRM がそのケースを内部で処理すると思っていました。明らかに、そうではありません (私が得たエラーはこれを示しています)。したがって、このケースを検出して別のことを行う必要があり、これを動的に実行したいと考えています。

動的とは、私のコードには定義済みの FetchXML 文字列がたくさんないことを意味します。特定のエンティティ、ビュー、または検索要件のためにコード化されていません。また、新しいエンティティまたはビューが追加または変更されるたびに変更する必要はありません。この文脈では「動的」という言葉は適切ではないかもしれませんが、他に何と呼べばいいのかわかりません。エンティティ/ビューに依存しない?

次のようなコードは必要ありません。

SearchResults ExecuteView(string entityLogicalName, string searchString)
{
    switch(entityLogicalName)
    {
        case "account":
            return searchAccounts(searchString);

        ... all other enties ...

        default:
            throw new Exception("Unknown entity type: " + entityLogicalName);
    }
}


SearchResults searchAccounts(searchString)
{
    var fetchXml = string.Format(@"
<fetch>
      <entity name=""account"">
        <link-entity name=""contact"" from=""contactid"" to=""primarycontactid"">
            <attribute name=""name"" alias=""name"" />
            <filter type=""and"">
                <condition attribute=""name"" operator=""like"" value=""%{0}%"" />
            </filter>
        </link-entity>
      </entity>
</fetch>", searchString);

    return executeSearch(fetchXml);
}

CRM の変更 (エンティティの追加/削除、ビューの追加/削除/更新) に合わせてコードを更新する必要があるためです。

4

3 に答える 3

2

CRMが文字列を使用してGUIDを検索する方法を推測できるかどうかはわかりませんが、利用できない可能性のある前処理またはバックエンドを実行していると思われます。(本当に知りたい場合は、CRM .dll を逆コンパイルしてみてください。ただし、時間がかかる場合があります)。

そのため、別の方法として、FetchXml をさらに操作する処理の段階を提案します。メタデータ サービスを使用してこれを行うと、ハードコーディングなしで回避できるはずです。

したがって、アカウントのフェッチを例にとると、xml を編集して id 属性をname追加する必要があると思いますprimarycontactidname。これは FilteredView のデータベース列の名前であり、FetchXml から利用できると思います。(それが機能しない場合は、名前のフィルターを追加しlink-entityて、既存の条件を削除します)。

したがって、追加するタイミングがわかりますname

  1. 簡易検索ビューの検索基準を取得します。
  2. 条件ごとに、メタデータ サービスを使用して CRM を検索します
  3. フィールド タイプが の場合はEntityReference、クイック ファインド ビューの検索を適切な条件で更新します。
于 2013-03-13T22:27:52.990 に答える
2

私はジェームズの答えに賛成票を投じました。それはあなたの質問に対する正しい答えだと思うからです。ただし、Web ページから検索できるようにするエンティティごとに、特別なシステム ビューを作成することが、全体としてより良い解決策になる可能性があります。命名規則を使用して、Web ページが検索するシステム ビューを認識できるようにします。システム ビューで、条件フィールドに {0} を指定し、通常どおりコードで置き換えます。このようにして、Metadata サービスへのクエリのオーバーヘッドなしで、必要な複雑な FetchXML を作成できます。おまけとして、この新しいシステム ビューを無効にして、CRM UI に表示されないようにします。

-以下のコメントの後に追加:

クイック ファインドは、実際には「ルックアップ/ビューをフィルター処理」しません。CRM UI の [クイック検索] ボックスにクエリを入力しても、現在のビューはフィルター処理されません。結果は [クイック検索] ビューを使用して表示されます ([ビュー] ドロップダウンを参照)。ご覧のように、このビューは特別な FetchXML を使用します - それは "isquickfindfields" 属性を使用します。この属性は、クエリを送信する前に、この FetchXML を前処理し、ノードを更新してそれらの関係フィールドの FetchXML を修正するための CRM UI へのフラグである必要があります。

この代替 UI ですべてのシステム ビューを表示することを意図しているが、クイック ファインド検索ボックスのようなものでそれらすべてをフィルタリングできるようにする場合は、CRM UI とはまったく異なるものについて話していることになります。:)

この代替 UI で同じ簡易検索ビュー パラメーターを使用するだけの場合でも、CRM で簡易検索ビューを模倣する非表示のシステム ビューを 1 つ作成することをお勧めします。このビューの背後にある FetchXML は「通常」であり、メタデータ サービスを呼び出さなくても検索テキストを挿入できます。

于 2013-03-17T05:58:17.437 に答える
0

私はあなたの質問を理解したと思います。primarycontactidは名前ではなく、この場合は連絡先のレコードを表すGUIDです。ユーザーがこのフィールドを検索する各レコードのGUIDを知らない限り、意味がありません。ただし、連絡先の内部を検索する必要があるため、リンク(SQLの結合に相当)を実行する必要があります。リンクエンティティの例でFetchXmlを使用する方法についてはこちらをご覧ください。

今あなたがしたい例:

<fetch>
      <entity name="account">
        <link-entity name="contact" from="contactid" to="primarycontactid">
            <attribute name="name" alias="name" />
            <filter ... />
        </link-entity>
      </entity>
</fetch>

C#でFetchXMLを動的に実行します。

string fetchrequest = string.Format(
@"<fetch mapping='logical' aggregate='true'>
    <entity name='queueitem'>
        <attribute name='queueitemid' alias='c' aggregate='count'/>
        <filter type='and'>
            <condition attribute='objecttypecode' operator='ne' value='4406'/>
            <condition attribute='queueid' operator='eq' value='{0}'/>
        </filter>
    </entity>
</fetch>", queueid.ToString());

string fetchresult = crmservice.Fetch(fetchrequest);
XmlDocument document = new XmlDocument();
document.LoadXml(fetchresult);
Console.Writeline("numero de elementos:" + document.SelectSingleNode("//resultset/result/c").InnerText));
于 2013-03-13T16:08:43.523 に答える