【问题标题】:Linq Queryable from OrganizationServiceProxy throws exception when comparing two fields比较两个字段时,来自 OrganizationServiceProxy 的 Linq Queryable 抛出异常
【发布时间】:2019-12-13 22:09:41
【问题描述】:

我已尝试减少此示例以删除 OrganizationServiceProxy/XrmServiceContext,但现在我相信问题源于那里。我正在使用 Microsoft 的 CrmSvcUtil.exe 生成的代码从 Dynamics 365 实例中提取数据。这是相关的sn-p:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
CrmServiceClient client = new CrmServiceClient(userName, CrmServiceClient.MakeSecureString(password), string.Empty, orgName, isOffice365: true);

using (OrganizationServiceProxy service = client.OrganizationServiceProxy)
{
    XrmServiceContext crm = new XrmServiceContext(service);

    var q = crm.CreateQuery<Account>();

    List<Account> accounts = q.Where(x => x.AccountNumber != x.dynamics_integrationkey).ToList();
}

我得到以下异常:

从范围“”引用了“{company-specific}.Account”类型的变量“x”,但未定义

这发生在 Linq 实际执行时的最后一行。只有当它通过 Microsoft.Xrm.Sdk.Client.OrganizationServiceContext 创建时,我才会收到错误消息。

我检查过的内容:

  • 在比较同一对象(不仅仅是帐户)上的任意两个字段时,即使两者的数据类型完全相同。
  • 如果我将 crm.CreateQuery... 替换为手动填充的 List...AsQueryable(),则 Linq 可以正常工作
  • 最令人沮丧的是,如果我通过带有List&lt;Account&gt; a = q.ToList(); 的中间列表首先对结果集进行光栅化,那么这一切都可以正常工作。因为我已经放弃了任何延迟加载,所以运行需要更长的时间,但它可以正常运行。
  • 我查看了与 从范围''引用但未定义 Linq 错误相关的其他答案,但它们都是关于格式错误的 Linq。我知道这个 Linq 格式正确,因为如果我更改底层 Queryable,它就可以正常工作。

显然 List...ToQueryable() 和由 XrmServiceContext 创建的 Microsoft.Xrm.Sdk.Linq.Query (从 Microsoft. Xrm.Sdk.Client.OrganizationServiceContext),但我不知道它是什么。

【问题讨论】:

    标签: c# linq dynamics-crm microsoft-dynamics


    【解决方案1】:

    您尝试构建的查询(将字段值与同一实体上的另一个字段值进行比较)在 Dynamics 中是不可能的。

    LINQ 提供程序仍然在后台使用 QueryExpression,这意味着您的 LINQ 条件将在 ConditionExpression 中转换,并且无法进行比较。

    类似问题:

    https://social.microsoft.com/Forums/en-US/d1026ed7-56fd-4f54-b382-bac2fc5e46a7/linq-and-queryexpression-compare-entity-fields-in-query?forum=crmdevelopment

    Dynamics QueryExpression - Find entity records where fieldA equals fieldB

    【讨论】:

    • 谢谢,好像是这样。我必须围绕它编写代码并接受性能打击或实施 Aron 的建议。
    【解决方案2】:

    今天早上,我意识到我的答案包含在 LINQ 查询中将两个字段相互比较的缺陷。我的错。感谢 Guido 指出这是不可能的。

    我使用 3rd 方工具生成代理类,所以我不熟悉 XrmServiceContext 类。但是,我已经确认 XrmServiceContext 继承自 Microsoft.Xrm.Client.CrmOrganizationServiceContext,后者继承自 Microsoft.Xrm.Sdk.Client.OrganizationServiceContext

    我使用OrganizationServiceContext 进行 LINQ 查询。

    如果您首先通过在查询中调用ToList() 来检索所有帐户,那么您可以对这两个字段进行比较。如果您有太多帐户无法一次全部加载,您可以分页浏览它们并随时存储不匹配的帐户。
    而且,我可能会检索字段的子集而不是整个记录(如图所示)。

    var client = new CrmServiceClient(userName, CrmServiceClient.MakeSecureString(password), string.Empty, orgName, isOffice365: true);
    
    using (var ctx = new OrganizationServiceContext(client))
    {
        var q = from a in ctx.CreateQuery<Account>()
                where a.AccountNumber != null
                && a.dynamics_integrationkey != null
                select new Account 
                {
                    Id = a.AccountId,
                    AccountId = a.AccountId,
                    Name = a.Name,
                    AccountNumber = a.AccountNumber,
                    dynamics_integrationkey = a.dynamics_integrationkey
                };
    
        var accounts = q.ToList();
        var mismatched = accounts.Where(a => a.AccountNumber != a.dynamics_integrationkey).ToList()
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多