LINQ where子句在第二个地方抛出错误

Phi*_*ley 2 c# linq linq-to-entities dynamics-crm-2011 dynamics-crm-online

UPDATE

即使搜索联系人firstName或LastName也会导致问题:

var contacts =
            (
                from c in context.ContactSet
                join m in context.py3_membershipSet on c.ContactId equals m.py3_Member.Id
                where m.statuscode.Value == 1
                && ((c.FirstName != null && c.FirstName == searchTerm) || (c.LastName!=null && c.LastName == searchTerm) || (c.FullName != null && c.FullName == searchTerm))  
                orderby c.LastName
                select new
                {
                    ContactId = c.ContactId,
                    FirstName = c.FirstName,
                    LastName = c.LastName,
                    BranchCode = c.py3_BranchArea,
                    Branch = (c.FormattedValues != null && c.FormattedValues.Contains("py3_brancharea") ? c.FormattedValues["py3_brancharea"] : "N/a"),
                    JobTitle = c.JobTitle,
                    Organisation = (c.ParentCustomerId != null ? c.ParentCustomerId.Name : "N/a"),
                    joinedAsCode = c.py3_SOLACEMemberJoinedAs,
                    JoinedAs = (c.FormattedValues != null && c.FormattedValues.Contains("py3_solacememberjoinedas") ? c.FormattedValues["py3_solacememberjoinedas"] : "N/a"),
                    Expertise = (c.py3_SOLACEMemberAreasofExpertise != null && c.py3_SOLACEMemberAreasofExpertise.Trim() != String.Empty ? c.py3_SOLACEMemberAreasofExpertise : "N/a"),
                    Title = c.Salutation
                }
            );
Run Code Online (Sandbox Code Playgroud)

哪个尖叫回来:

'py3_membership'实体不包含Name ='firstname'的属性.


我有以下代码,它来自在线CRM的一些信息:

        var context = new XrmServiceContext();
    var contacts1 =
        (
            from c in context.ContactSet
            join m in context.py3_membershipSet on c.ContactId equals m.py3_Member.Id
            where m.statuscode.Value == 1

            orderby c.LastName
            select new
            {
                ContactId = c.ContactId,
                FirstName = c.FirstName,
                LastName = c.LastName,
                BranchCode = c.py3_BranchArea,
                Branch = (c.FormattedValues != null && c.FormattedValues.Contains("py3_brancharea") ? c.FormattedValues["py3_brancharea"] : "N/a"),
                JobTitle = c.JobTitle,
                Organisation = (c.ParentCustomerId != null ? c.ParentCustomerId.Name : "N/a"),
                joinedAsCode = c.py3_SOLACEMemberJoinedAs,
                JoinedAs = (c.FormattedValues != null && c.FormattedValues.Contains("py3_solacememberjoinedas") ? c.FormattedValues["py3_solacememberjoinedas"] : "N/a"),
                Expertise = (c.py3_SOLACEMemberAreasofExpertise != null && c.py3_SOLACEMemberAreasofExpertise.Trim() != String.Empty ? c.py3_SOLACEMemberAreasofExpertise : "N/a")
            }
        );
Run Code Online (Sandbox Code Playgroud)

然后我将它作为数组绑定到datalist,这一切都正常.

但是,我希望能够将结果限制为从下拉列表中选择的值,并期望以下工作:

        var context = new XrmServiceContext();
    var contacts1 =
        (
            from c in context.ContactSet
            join m in context.py3_membershipSet on c.ContactId equals m.py3_Member.Id
            where m.statuscode.Value == 1 &&
                c.FormattedValues["py3_brancharea"] == ddlBranchTags.SelectedItem.Value


            orderby c.LastName
            select new
            {
                ContactId = c.ContactId,
                FirstName = c.FirstName,
                LastName = c.LastName,
                BranchCode = c.py3_BranchArea,
                Branch = (c.FormattedValues != null && c.FormattedValues.Contains("py3_brancharea") ? c.FormattedValues["py3_brancharea"] : "N/a"),
                JobTitle = c.JobTitle,
                Organisation = (c.ParentCustomerId != null ? c.ParentCustomerId.Name : "N/a"),
                joinedAsCode = c.py3_SOLACEMemberJoinedAs,
                JoinedAs = (c.FormattedValues != null && c.FormattedValues.Contains("py3_solacememberjoinedas") ? c.FormattedValues["py3_solacememberjoinedas"] : "N/a"),
                Expertise = (c.py3_SOLACEMemberAreasofExpertise != null && c.py3_SOLACEMemberAreasofExpertise.Trim() != String.Empty ? c.py3_SOLACEMemberAreasofExpertise : "N/a")
            }
        );
Run Code Online (Sandbox Code Playgroud)

但是,这会引发以下错误:

Invalid 'where' condition. An entity member is invoking an invalid property or method.
Run Code Online (Sandbox Code Playgroud)

即使我硬编码分支标准而不是DDL值,它也是一样的.我也试过在contacts1集上做一个选择,例如:

var results = contacts1.select(c=> c.BranchTag == ddlBranchTags.SelectedItem.Value
Run Code Online (Sandbox Code Playgroud)

但是这会引发同样的错误.

如果我删除branchTag where子句它按预期工作.我认为公平地假设我已经对此任性,所以任何有用的/建设性的指针(对于LINQ newb)都会非常感激.谢谢.

Gab*_*yer 5

LINQ-to-CRM实际上在它可以支持的表达形式方面相当有限.如果你考虑它在幕后做了什么 - 将整个LINQ表达式转换为CRM QueryExpression - 这更有意义.

基本上,期望能够将任意C#嵌入到您的查询中是有效的(即使它编译),因为无法将所有代码转换为CRM查询.查询提供程序可以假设足够聪明,可以确定它可以作为查询提交给CRM,以及它必须执行客户端以获得最终所需结果的代码,但这通常是一个非常难的问题 - LINQ之一提供商不会尝试解决.

在Where子句中,LINQ提供程序扫描表达式的基本形式<attribute name accessor> <simple comparison> <value>.它理解早期绑定的codegen属性访问器(entity.Attribute_name),索引器访问(entity["attribute_name"])和entity.GetAttributeValue<T>("attribute_name")访问.这些是您可以在Where子句(或OrderBy子句)中的比较左侧使用的唯一内容.在您的第二个查询中,您正在访问FormattedValues,查询提供程序不理解/不支持.

另一个限制是单个Where子句只能寻址一个"目标"实体.因此,不支持在单个谓词中对"m"和"c"都有过滤器的情况.我不太清楚这种限制的原因,但事实就是如此.您仍然可以通过将两个条件(由当前查询中的&&连接)拆分为两个单独的Where子句来完成等效过滤器.

想要编写LINQ-to-CRM查询就好像使用LINQ-to-Objects一样,但这样做通常会令人沮丧.LINQ-to-CRM有些限制,但其中许多限制都是从它构建的底层CRM SDK查询系统继承而来的.只要记住这些限制,它仍然是编写CRM查询的一个不错的API.

如果您正在编写一个要求您执行某些任意代码来过滤/排序/映射结果的查询,那么应该使用的一般技术是将您的查询分为两部分:应该提交的查询CRM,以及您的aribitrary代码转换.你写的,使用类似的查询力评价让你的CRM数据数据最有效的查询,你可以ToListToArray(如LINQ另有惰性计算),然后继续进行该评估的结果,你的代码.