2

当社の CRM 2011 データベースには、約 20000 件の連絡先があり、SDK を使用してそれらすべてをループする必要があります。現在、次の linq クエリの実行に非常に時間がかかることがわかりました。

Dim contactList = From c In orgService.ContactSet 
  Select New With {
    Key .ContactId = c.ContactId,
    Key .EMailAddress1 = c.EMailAddress1,
    Key .ListIds = From l In c.listcontact_association Select l.ListId
  }

ご覧のとおり、必要なのは、各連絡先のいくつかのフィールドと、関連付けられたマーケティング リスト ID のリストだけです。各連絡先結果内で (リスト ID を取得するために) 追加のクエリを実行しているため、おそらく時間がかかっていますか?

私は Linq にかなり慣れていないので、上記が実際の FetchXML 通信にどのように変換されるかわかりません。その情報を取得してクエリの実行時間を短縮するより効率的な方法はありますか?

詳細情報: CRM データベースを CreateSend データベースと同期するコードを作成しています。そのため、CS データベースに追加するだけでなく、リスト メンバーシップの変更を反映し、必要に応じて各連絡先のアクティビティやその他の情報を更新して、すべての連絡先レコードを確認する必要があります。同期処理は最終的に CRM サーバー自体で夜間に実行されるため、実行に時間がかかることが予想されますが、もちろんできるだけ効率的に実行したいと考えています。

4

2 に答える 2

1

これ以上の情報がない場合、クエリは実際には 2 つのように見えます。1 つは連絡先のリストを取得するためのクエリで、もう 1 つはリスト ID のリストを取得するためのクエリです。これは、SQL Server が 20,000 の連絡先の完全なリストを返していることを意味し、コードは連絡先ごとに、関連するリスト ID のリストを SQL Server に要求します。

これは、SQL Server に対して20,000 + 1 回の個別の呼び出しを行っていることを意味します (ただし、これは実際には抽象化された合計です。CRM SQL トランスレーターは実際にはそれ以上の呼び出しを行いますが、大きなオーバーヘッドは追加されません)。

したがって、本当にやりたいことは、すべてのデータを取得するクエリを1 つだけ作成し、それを使用して作業を開始することです。私は翻訳を行うほど VB.NET に精通していませんが、以下の C# コードを使用すると、ほとんどの場合、翻訳を行うことができます。

// Gets all contacts and list ids in a flat result set
var contacts = from c in orgService.ContactSet
               join lms in orgService.ListMemberSet on c.ContactId equals lms.EntityId.Id into leftJoinedContact
               from ljc in leftJoinedContact.DefaultIfEmpty()
               where ljc.EntityType == Xrm.Contact.EntityLogicalName
               select new
               {
                   c.ContactId,
                   c.EMailAddress1,
                   ljc.ListId
               };

// Calls .ToList() to put the result set in memory
var contactList = contacts.ToList();

// Manipulates the result set in memory, grouping by contact info
var newContactList = contactList.GroupBy(x => new {x.ContactId, x.EMailAddress1})
    .Select(x => new {x.Key.ContactId, x.Key.EMailAddress1, Ids = x.Select(y => y.ListId).ToList()})
    .ToList();

// var contactsWithListIds = newContactList.Where(x => x.Ids.Where(y => y != null).Any()).ToList();
// var contactsWithoutListIds = newContactList.Where(x => x.Ids.Where(y => y != null).Any()).ToList();

foreach (var contact in newContactList)
{
    throw new NotImplementedException();
}
于 2012-06-26T16:36:37.797 に答える
0

はい!

しかし、もっと情報が必要です。最速の方法は、単純な SQL (つまり、フィルター処理されたビュー) を使用することです。

2 番目に速い方法は、そのままの FetchXML を使用することです (パフォーマンスの点で linq がこれと同等であると議論する人もいるかもしれませんが)。

ただし、クエリをフィルター処理して 20,000 レコードを必要なレコードだけに減らすことができれば、時間を最大限に節約できます。最初の質問は、なぜ 20,000 レコードを反復処理しているのかということです。それらをすべて処理する必要がありますか、それとも特定の基準についてすべてをチェックし、それらが基準に一致するかどうかに基づいて何かを行う必要がありますか?

于 2012-06-25T17:12:49.760 に答える