Оператор соединения Linq to CRM (с ранним ограничением) генерирует исключение, когда лямбда-выражение не - PullRequest
6 голосов
/ 17 октября 2011

Есть ли ошибка в поставщике Microsoft linq to CRM, или я делаю что-то, что linqToCrm не поддерживает?

У меня есть простая функция, которая определяет, назначена ли пользователю роль, которая не работает.

public static bool IsSystemUserInRole(Guid systemUserId,
                                      string roleName,
                                      Microsoft.Xrm.Sdk.IOrganizationService service)
{
    using (var crmService = new CrmContext(service))
    {
        return (from sr in crmService.SystemUserRolesSet
                join r in crmService.RoleSet
                    on sr.RoleId.Value equals r.RoleId.Value
                where sr.SystemUserId.Value == systemUserId && r.Name == roleName
                select sr.SystemUserId).FirstOrDefault() != null;
    }
}

Но как ни странно, если я переписываю его как два лямбда-выражения, он работает нормально.

public static bool IsSystemUserInRole(Guid systemUserId,
                                      string roleName,
                                      Microsoft.Xrm.Sdk.IOrganizationService service)
{
    using (var crmService = new CrmContext(service))
    {
        var role = crmService.RoleSet.FirstOrDefault(r => r.Name == roleName);
        return role != null 
                && crmService.SystemUserRolesSet.FirstOrDefault(
                    ur => ur.SystemUserId == systemUserId
                          && ur.RoleId == role.RoleId) != null;
    }
}

Исключение составляет

System.ServiceModel.FaultException`1 [Microsoft.Xrm.Sdk.OrganizationServiceFault]: сущность 'SystemUserRoles' не содержит атрибута с именем = «имя». (Сведения об ошибке равны Microsoft.Xrm.Sdk.OrganizationServiceFault).

и трассировка стека

Трассировка стека серверов: в System.ServiceModel.Channels.ServiceChannel.HandleReply (операция ProxyOperationRuntime, ProxyRpc & rpc) в System.ServiceModel.Channels.ServiceChannel.Call (строковое действие, логический односторонний режим, операция ProxyOperationRuntime, Object [] ins, Object [] outs, TimeSpan timeout) в System.ServiceModel.Channels.ServiceChannelProxy.InvokeService (метод IMethodCallMessageCall, операция ProxyOperationRuntime) в System.ServiceModel.Channels.ServiceChannelProxy.Invoke (сообщение IMessage)

Исключение переброшено в [0]: в System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage (IMessage reqMsg, IMessage retMsg) в System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke (MessageData & msgData, тип Int32) в Microsoft.Xrm.Sdk.IOrganizationService.Execute (запрос OrganizationRequest) в Microsoft.Xrm.Sdk.Client.OrganizationServiceProxy.ExecuteCore (запрос OrganizationRequest) в Microsoft.Xrm.Sdk.Client.OrganizationServiceProxy.Execute (запрос OrganizationRequest) в Microsoft.Xrm.Sdk.Client.OrganizationServiceContext.Execute (запрос OrganizationRequest) в Microsoft.Xrm.Sdk.Linq.QueryProvider.RetrieveEntityCollection (запрос OrganizationRequest, источник NavigationSource) в Microsoft.Xrm.Sdk.Linq.QueryProvider.Execute (QueryExpression qe, Boolean throwIfSequenceIsEmpty, Boolean throwIfSequenceNotSingle, проекция проекции, источник NavigationSource, список 1 linkLookups, String& pagingCookie, Boolean& moreRecords) at Microsoft.Xrm.Sdk.Linq.QueryProvider.Execute[TElement](QueryExpression qe, Boolean throwIfSequenceIsEmpty, Boolean throwIfSequenceNotSingle, Projection projection, NavigationSource source, List 1 linkLookups) в Microsoft.Xrm.Sdk.Linq.QueryProvider.Execute [TElement] (выражение выражения) в Microsoft.Xrm.Sdk.Linq.QueryProvider.System.Linq.IQueryProvider.Execute [TResult] (выражение выражения) в System.Linq.Queryable.FirstOrDefault [TSource] (источник IQueryable`1) в CRM.Business.IntegrationServices.SystemUserService.IsSystemUserInRole (Guid systemUserId, String roleName, IOrganizationService service) в CRM.Plugin.OnExecute (поставщик IServiceProvider)

1 Ответ

7 голосов
/ 17 октября 2011

Where операторы от разных сущностей необходимо вводить в отдельно, где операторы .

Предложение where применяет фильтр к результатам, часто используя Логическое выражение Фильтр указывает, какие элементы исключать из исходной последовательности. Каждый пункт where может содержать только условия против одного типа объекта. Сложное состояние участие нескольких объектов недействительно. Вместо этого каждый объект должен быть отфильтрованы в отдельных пунктах where.

Ниже следует, вероятно, позаботиться об этом.

public static bool IsSystemUserInRole(Guid systemUserId,
                                      string roleName,
                                      Microsoft.Xrm.Sdk.IOrganizationService service)
{
    using (var crmService = new CrmContext(service))
    {
        return (from sr in crmService.SystemUserRolesSet
                join r in crmService.RoleSet
                    on sr.RoleId.Value equals r.RoleId.Value
                where sr.SystemUserId.Value == systemUserId
                where r.Name == roleName
                select sr.SystemUserId).FirstOrDefault() != null;
    }
}
...