【问题标题】:Select a percentage of records using CRM 2011 Dynamic Entity使用 CRM 2011 动态实体选择一定百分比的记录
【发布时间】:2011-11-18 00:46:46
【问题描述】:

我正在开发通过动态实体(如 Microsoft.Xrm.Sdk.Entity,后期绑定方法)使用 CRM 2011 数据的服务。我故意不使用 Xrm.cs 方法(早期绑定)以保持我的解决方案通用。

另外,我想避免直接连接到 CRM 数据库(例如 EDMX),因为这会阻止我的解决方案可用于托管 CRM(例如,没有直接的数据库访问权限)。

我有以下(简化的)要求,我真的在为选择标准苦苦挣扎:

随机 7% 的记录需要选择(并更新)。

在 SQL 中,选择标准相对容易——我知道如何选择随机百分比的记录。比如:

SELECT TOP 7 PERCENT * FROM
(
    SELECT TOP 1000 NEWID() AS Foo, [someColumns]
    FROM [someTable]
)
AS Bar ORDER BY Bar.Foo ASC

这非常有效。我收集的 LINQ 等价物类似于:

from e in someEntities
orderby Guid.NewGuid()
select e;

但有一个问题,我不知道如何将 LINQ 与 CRM 2011 动态实体一起使用 - 相反,他们坚持使用一些限制性 QueryExpression 类/语法或 fetchXML,如 this page (MSDN) 所示。

我已经确定了满足此要求的以下选项:

  1. 使用动态实体,将整个记录集返回到列表中,然后简单地按索引随机选择。然而,这涉及通过互联网数据服务返回多达 10,000 条记录,这可能会很慢/不安全/等等。

  2. 使用 fetchXML 语句。不幸的是,我不知道 fetchXML,所以我不知道是否可以执行 COUNT、TOP、PERCENT 或 NEWID() 之类的操作。

  3. 使用 Xrm.cs 和 LINQ,或使用存储过程或 SQL 视图。所有这些选项都意味着将解决方案绑定到直接数据库连接和/或早期绑定,这是不可取的。

  4. 对客户说不。

任何建议将不胜感激! fetchXML 可以执行这个查询吗?有没有更好的方法来做到这一点?

【问题讨论】:

    标签: dynamics-crm-2011 entity fetchxml


    【解决方案1】:

    FetchXML 不支持此功能,因此您只能选择 1 或 3。您是对的,3 仅适用于 On Premise 版本,因为您无法使用 CRM Online 产品直接连接到 SQL。但是,除非您绝对确定客户将迁移到 CRM Online,否则我会采用这种方式。如果您必须使用 1,您至少可以将返回的列限制为仅为记录的 GUID,以减少有效负载大小。然后,当您选择随机记录时,只需在需要时获取它们的附加列(当然,由于“闲聊”,这最终可能会变慢,具体取决于您正在处理的随机记录数量)。

    【讨论】:

    • 我认为需求制定者坚持该解决方案适用于托管环境,因此我将返回一个 id 列表并将它们随机化。我已投票,如果此方法成功,将标记为答案。谢谢:)
    • 我已经能够使用上述方法完成这项工作;仅将完整集作为 id 列表返回,然后在内存中进行随机选择后选择完整数据。因此,我将其作为答案,因为它确实有效,但是我建议有类似要求的任何人也应阅读 jamnap 答案中的信息;我还不知道哪种解决方案更有效。
    【解决方案2】:

    Dynamics CRM 2011 在这一点上无法为您提供 SQL 和其他 LINQ 提供商可以提供的查询能力,所以我真的相信您会想要对客户说不并且 del> 如果他/她想要这种灵活性,请转到本地版本。

    话虽如此,方法#1 的一种变体是,而不是一次获取所有行然后选择您的随机集,而是一次从实体中获取一个随机集一行,直到您获得所需的行数想。这种方法的缺点是对数据库的调用不是一次,而是多次,这会降低整体检索速度。下面是 POC。

    至于 #2,我相信使用 fetchXml 可以处理您的所有请求,并取得一定程度的成功。事实上,获取aggregated data的唯一方法是使用fetchXml,它还支持paging

    至于 #3,本机 SQL 是此时您从数据中获取您想要的一切的最佳选择,但尽管如此,虽然 the LINQ provider is limited,但将 SQL 语句转换为 LINQ 比 fetchXML 容易得多,和it does support late-binding/dynamic entities

    //create a list of random numbers
    List<int> randomNumbers = new List<int>();
    
    //declare a percentage of records you'd like to retrieve
    double pctg = 0.07;
    
    //use FetchXML to count the # of rows in the table
    string fetchXml = @"<fetch aggregate='true'>
    <entity name='salesorder'>
    <attribute name='salesorderid' aggregate='count' alias='countIds' distinct='false' />
    </entity>
    </fetch>";
    EntityCollection result = _service.RetrieveMultiple(new FetchExpression(fetchXml));
    int rowCount = int.Parse(result.Entities[0].FormattedValues["countIds"].Replace(",", ""));
    
    //initalize the random number list for paging
    for (int i = 0; i < Math.Ceiling(pctg * rowCount); i++)
    {
        randomNumbers.Add((new Random(unchecked((int)(DateTime.Now.Ticks >> i)))).Next(rowCount - 1));
    }
    randomNumbers.Sort();
    
    //page through the rows one at a time until you have the number of rows you want
    using (OrganizationServiceContext osc = new OrganizationServiceContext(_service))
    {
        foreach (int r in randomNumbers)
        {
            foreach (var er in (from c in osc.CreateQuery("salesorder")
                                //not especially useful to use the orderby option as you can only order by entity attributes
                                //orderby c.GetAttributeValue<string>("name")
                                select new
                                {
                                    name = c.GetAttributeValue<string>("name")
                                }).Skip(r).Take(1))
            {
                Console.WriteLine(er.name);
            }
    
        }
    }
    

    【讨论】:

    • 我没想过使用分页 cookie - 好主意!
    • 这个答案中有一些非常有趣的信息,我当然不知道 LINQ 可以按照 MSDN 链接中显示的方式与动态实体一起使用。 FetchXML 可能是执行此操作的更好方法,我将不得不进行试验,看看它在性能方面如何与建议的其他方法进行比较。非常感谢您的回复。
    猜你喜欢
    • 2012-07-12
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多