【问题标题】:CRM 2011 sdk - quickest/most efficient way to get contact info + associated list IDsCRM 2011 sdk - 获取联系信息 + 相关列表 ID 的最快/最有效方式
【发布时间】:2012-06-25 16:51:21
【问题描述】:

我们的 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 服务器本身上每晚运行,因此预计需要一些时间才能运行,但我当然希望使其尽可能高效。

【问题讨论】:

  • 什么需要很长时间 - 获取所有联系人的查询,还是遍历所有 20,000 个联系人?

标签: vb.net linq dynamics-crm-2011


【解决方案1】:

在没有更多信息的情况下,您的查询实际上是两个查询 - 一个查询用于获取联系人列表,然后另一个查询用于获取列表 ID 列表。这意味着 SQL Server 将返回 20,000 个联系人的完整列表,然后对于每个联系人,您的代码会向 SQL Server 询问相关列表 ID 的列表。

这意味着您正在对 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();
}

【讨论】:

    【解决方案2】:

    是的!

    但我们需要更多信息。最快的方法是使用直接 SQL(即过滤视图)。

    第二快的方法是直接使用 FetchXML(尽管有些人可能会争论 linq 在性能方面与此相当)。

    如果您可以过滤查询以将 20,000 条记录减少到只需要的记录,那么您将节省最多的时间。所以我的第一个问题是你为什么要遍历 20,000 条记录?您是否需要全部处理它们,还是需要根据某些条件检查它们,然后根据它们是否符合条件来做一些事情?

    【讨论】:

    • 您好,感谢您的帮助。我已经用更多信息更新了描述。这是一个同步操作,所以我确实需要查看所有记录。
    • 保罗,你那个接近我的-1。你有什么证据来支持你的说法,即直接 SQL 是最快的,并且在那上面过滤了视图?然后你说直接FetchXml更快,再提Linq。在没有可靠测试的情况下,没有关于哪个更快的争论。
    • 但我确实想为有关预过滤的部分提供 +1。好矛盾。
    • @PeterMajeed - 我错误地假设没有什么比直接访问数据库表本身更好(知道您失去了所有基于角色的安全性并让自己陷入可能与 Microsoft 执行中断有关的问题)改变)。 Paul - 由于 Linq 被转换为查询表达式,它们将比 LINQ 稍微快一些(对于大多数查询,我们说的是毫秒),因为 SDK 不需要做任何翻译工作。
    • @Daryl:肯定是一大堆东西,这主要是因为 CRM API 对 查询逻辑 的限制。但是,直接SELECT * FROM ___ (INNER JOIN ___ WHERE ___ ORDER BY ___ etc.),我不知道原生 SQL 查询比处理 FetchXml/Linq/QueryExpressions 有任何显着的速度优势。
    猜你喜欢
    • 2011-08-12
    • 2012-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-03
    • 2012-06-04
    • 2019-03-06
    相关资源
    最近更新 更多