private ICriterion CreateAnyOrAllCriterion(CollectionMethod method, ResolvedMemberExpression resolvedMember, LambdaExpression lambdaExpression)
        {
            Require.That(method.MethodType == MethodType.Any || method.MethodType == MethodType.All, "Invalid method type", "method");

            // Resolved member's name may contain multiple dots if it's inside a component (i.e. 'root.Component.Collection')
            int p = resolvedMember.Member.IndexOf('.');

            if (p == -1)
            {
                throw new ODataException(string.Format("Member '{0}' must have an alias.", resolvedMember.Member));
            }

            var collectionHolderAliasName = resolvedMember.Member.Substring(0, p);
            var collectionMemberName      = resolvedMember.Member.Substring(p + 1);

            Alias collectionHolderAlias;

            _context.AliasesByName.TryGetValue(collectionHolderAliasName, out collectionHolderAlias);

            if (collectionHolderAlias == null)
            {
                throw new ODataException(string.Format("Unknown alias '{0}'.", collectionHolderAliasName));
            }

            var subCriteriaAlias = _context.CreateUniqueAliasName();
            var detachedCriteria = DetachedCriteria.For(collectionHolderAlias.ReturnedType, subCriteriaAlias);

            MappedClassMetadata metadata;

            _context.SessionFactoryContext.MappedClassMetadata.TryGetValue(collectionHolderAlias.ReturnedType, out metadata);

            if (metadata == null)
            {
                throw new ODataException(string.Format("The type '{0}' isn't a NHibernate-mapped class.", collectionHolderAlias.ReturnedType.FullName));
            }
            if (metadata.IdentifierPropertyName == null)
            {
                throw new ODataException(string.Format("The type '{0}' doesn't have an identifier property.", collectionHolderAlias.ReturnedType.FullName));
            }

            detachedCriteria.Add(Restrictions.EqProperty(
                                     subCriteriaAlias + "." + metadata.IdentifierPropertyName,
                                     collectionHolderAliasName + "." + metadata.IdentifierPropertyName
                                     ));

            var lambdaAlias = _context.CreateUniqueAliasName();

            System.Type itemType;

            if (resolvedMember.ReturnedType == null || (itemType = TypeUtil.TryGetCollectionItemType(resolvedMember.ReturnedType)) == null)
            {
                throw new ODataException("Cannot get collection item type");
            }

            _context.AddAlias(new Alias(lambdaAlias, string.Empty, itemType));

            // The inner joined alias to collection items must be created in any case (whether the lambda expression is specified or not)
            detachedCriteria.CreateAlias(subCriteriaAlias + "." + collectionMemberName, lambdaAlias, JoinType.InnerJoin);

            detachedCriteria.SetProjection(Projections.Constant(1));

            if (lambdaExpression != null)
            {
                if (method.MethodType == MethodType.All)
                {
                    lambdaExpression = (LambdaExpression)InverseVisitor.Invert(lambdaExpression);
                }

                _context.PushLambdaContext(lambdaExpression.ParameterName, itemType, lambdaAlias);

                try
                {
                    var lambdaNormalizeVisitor = new AliasingNormalizeVisitor(
                        _context,
                        collectionHolderAlias.ReturnedType,
                        collectionHolderAliasName
                        );

                    var bodyExpression = lambdaExpression.Body.Visit(lambdaNormalizeVisitor);

                    var criterion = bodyExpression.Visit(new CriterionVisitor(_context));

                    if (criterion != null)
                    {
                        detachedCriteria.Add(criterion);

                        foreach (var alias in lambdaNormalizeVisitor.Aliases.Values)
                        {
                            detachedCriteria.CreateAlias(alias.AssociationPath, alias.Name, JoinType.LeftOuterJoin);
                        }
                    }
                }
                finally
                {
                    _context.PopLambdaContext();
                }
            }

            if (method.MethodType == MethodType.Any)
            {
                return(Subqueries.Exists(detachedCriteria));
            }
            else
            {
                return(Subqueries.NotExists(detachedCriteria));
            }
        }
 public virtual T ResolvedMemberExpression(ResolvedMemberExpression expression)
 {
     throw new QueryNotSupportException();
 }
 public Expression ResolvedMemberExpression(ResolvedMemberExpression expression)
 {
     throw new InvalidOperationException();
 }
 public Expression ResolvedMemberExpression(ResolvedMemberExpression expression)
 {
     return(expression);
 }
Exemple #5
0
 public override IProjection ResolvedMemberExpression(ResolvedMemberExpression expression)
 {
     return(Projections.Property(expression.Member));
 }