0

编码:

var site = CrmRepository.QueryFor<Account>()
                .Where(a => a.iss_OperatorSiteId == OperatorSiteId.ToString())
                .FirstOrDefault();
SiteCases = CrmRepository.QueryFor<Incident>()
                    .Where(i => i.AccountId.Id == site.Id
                                && (i.iss_Status != new OptionSetValue(
                                      (int)StatusOptionSet.Closed) 
                                   && i.iss_Status != new OptionSetValue(
                                      (int)StatusOptionSet.PendingFinalization))
                                || (i.iss_ResolutionDate == null 
                                    || i.iss_ResolutionDate > 
                                          DateTime.Today.AddDays(-30))
                                || (ShowFullCaseHistoryBox.Checked))
                    .AsEnumerable()
                    .Select(i => new CrmCaseListItem(i))
                    .ToList();

细节:

  • CrmRepository是由 CrmSvcUtil 生成的 CRM Linq 上下文的包装器,使其适应IRepository用于其他数据存储的通用接口。该QueryFor<Incident>()调用等效CreateQuery<Incident>()于对上下文本身的调用。

  • iss_Status是“选项集”类型的属性。StatusOptionSet是一个枚举,旨在简化代码中选项值的使用。

  • iss_ResolutionDate是不言自明的,为了简单起见,包括而不是引用案例解决记录,因为在我们的工作流程中,案例实际上并没有“解决”,直到问题不仅得到解决,而且案例记录和相关记录已经已处理和审核,因此对于 SLA 义务,我们需要知道问题何时解决,而不是应用解决方案完全关闭案例的时间。

  • 基本思想是显示与特定帐户相关联的事件(我们称之为案例),这些事件要么处于打开状态,要么在过去 30 天内已关闭(已解决),或者用户希望查看完整历史记录(在在这种情况下,将检索所有已打开或已关闭的案例)。

  • ShowFullCaseHistoryBox是一个 Winforms 复选框;选中后,应检索帐户的完整案例历史记录。

  • CrmCaseListItem是用作 DataGridView 支持的 DTO;它在其构造函数中获取事件并公开显示在网格上的属性。

错误:

'where' 条件无效。实体成员正在调用无效的属性或方法。

问题:

我想做什么是无效的?第一个子句匹配帐户 ID(因此需要一个投影),它本身工作得很好,所以我必须假设它是其他子句之一,但我无法确定是哪一个。正在检查的事件的属性没有被投影或操纵,这对于 Queryables 来说是通常的禁忌,所以我在这里真的很茫然。

编辑(已再次编辑):

在通过一些测试来评估每个单独的条款之后,使用到目前为止的一些建议并将条款中所有已知的好元素重新组合在一起,这是最接近的工作:

var site = CrmRepository.QueryFor<Account>()
                .Where(a => a.iss_OperatorSiteId == OperatorSiteId.ToString())
                .FirstOrDefault();
SiteCases = CrmRepository.QueryFor<Incident>()
                .Where(i => (i.AccountId.Id == site.Id) &&
                       (
                           (i.iss_Status.Value != (int) StatusOptionSet.Closed
                            && i.iss_Status.Value != (int) StatusOptionSet.PendingFinalization)
                           || (i.iss_ResolutionDate != null
                               && i.iss_ResolutionDate.Value > DateTime.Today.AddDays(-30))
                       //|| ShowFullCaseHistoryBox.Checked
                       )
                )
                .AsEnumerable()
                .Select(i => new CrmCaseListItem(i))
                .ToList();

唯一仍然不起作用的是检查 CheckBox 以显示完整的案例历史记录(基本上覆盖了前两个关于状态或解决日期的条款中的任何一个)。它不能按原样工作(取消注释内联表达式)或者如果它被提取到变量中。其他一切似乎都按预期工作。这个功能是可选的,所以如果它根本不起作用,没办法,不怎么做,那么我会轻轻地把它告诉客户,但我真的很喜欢这个工作,因为我离得太近了。有什么想法吗?

4

1 回答 1

0

LINQ to CRM 必须转换为查询表达式。在处理查询表达式时,您必须使用选项集值的 int 值。尝试在您的选项集属性上调用 .Value ,然后将您的枚举转换为预期值,看看是否可以解决您的问题。

您还可以使用Early Bound Generator,它会在您的实体上创建 Early Bound Enum 属性。然后,您不必将枚举转换为整数,也不必放入.value其中。

于 2013-02-02T14:40:23.713 回答