これはゲームに少し遅れていることは知っていますが、これを実行しようとしている他の人のために、よりパフォーマンスの高い代替手段を追加したいと思います。
ある種のキャッシングを導入しない限り、メタデータの呼び出しは非常に遅いことで有名です。定期的に実行されるプラグインにメタデータ呼び出しを入れると、問題が発生する可能性があります。(MSは、メタデータの呼び出しが非常に遅い理由を実際に調べて修正する必要があります!)。
フィールドの存在を確認するだけの場合は、代わりに例外を強制します。確かに、見た目は良くなく、一部の伝道者はそれに眉をひそめるでしょうが、メタデータ呼び出しよりも最大3倍速く実行されることがわかりました。これは、少なくとも、プラグインをより定期的に実行するための許容可能なブラケットに入れます。
これは私が代わりに行うことです:
try
{
var query = new QueryExpression("account");
query.Criteria.AddCondition("accountid", ConditionOperator.Equal, "294450db-46c9-447e-a642-3babf913d800");
query.NoLock = true;
query.ColumnSet = new ColumnSet("xyz_fieldname");
service.RetrieveMultiple(query);
}
catch
{
// ignored
}
クエリ式を使用することには2つの利点があります。主キーであるIDに対して実行することです(IDは気にしないでください。フィールドが存在しない場合、コードは例外をスローするか、1または成功した場合はレコードなし)。つまり、目的はレコードを見つけることではなく、列を含めると例外が強制されるかどうかを確認することです。
クエリ式の2番目の利点は、nolockを使用して実行できることです。あなたは本当に結果セットを気にしません、ポイントは例外を強制することです。
メタデータへの複数/単一の呼び出しと例外をスローする複数/単一の取得の複数の呼び出しの間で変化するCRMオンラインでいくつかのテストを実行しました(C#ストップウォッチを使用してコードの順序を逆にするなど)。例外は常にメタデータを上回りました。同じコード内で複数の呼び出しを実行している場合は、約3倍速くジャンプします(最適化が機能すると思います)。いずれにせよ、ボトルネックはメタデータサービスへの呼び出しであり、キャッシングとコードの複雑さを導入するまで最適化できません。また、フィールドが存在する場合、例外は発生しません。これは、さらに別のパフォーマンスボーナスを意味します。
私がテストしていない唯一のシナリオは、頻繁に使用されるエンティティに対して実行することです...しかし、データベースにアクセスしすぎて、nolockの取得が許容可能な時間枠で戻らない場合は、おそらくより大きな問題が発生する可能性があります。