AddAlias() public method

public AddAlias ( Alias alias ) : void
alias Alias
return void
Esempio n. 1
0
        public override Expression MemberExpression(MemberExpression expression)
        {
            var type = _persistentClass;
            MappedClassMetadata mappedClass = null;
            var members       = expression.Members;
            var lastAliasName = _rootAlias;

            // If we are inside a lambda expression
            if (_context.ExpressionLevel > 1)
            {
                // Lambda member expression MUST start with a variable name
                var lambdaContext = _context.FindLambdaContext(members[0].Name);
                if (lambdaContext == null)
                {
                    throw new QueryException(ErrorMessages.Expression_LambdaMemberMustStartWithParameter);
                }

                type          = lambdaContext.ParameterType;
                lastAliasName = lambdaContext.ParameterAlias;

                members = members.Skip(1).ToList();
            }
            else if (members[0].Name == "$it")
            {
                // Special case: $it variable outside of lambda expression
                members = members.Skip(1).ToList();
            }

            if (type != null)
            {
                _context.SessionFactoryContext.MappedClassMetadata.TryGetValue(type, out mappedClass);
            }

            if (members.Count == 1)
            {
                Debug.Assert(members[0].IdExpression == null);

                string resolvedName = ResolveName(mappedClass, string.Empty, members[0].Name, ref type);
                if (string.IsNullOrEmpty(resolvedName))
                {
                    /**
                     * 01.06.2020: Throwing exception moved from "ResolveName" to here.
                     */
                    throw new QueryException(String.Format(
                                                 ErrorMessages.Resolve_CannotResolveName, members[0].Name, type)
                                             );
                }

                return(new ResolvedMemberExpression(
                           expression.MemberType,
                           (lastAliasName != null ? lastAliasName + "." : null) + resolvedName,
                           type
                           ));
            }

            var sb               = new StringBuilder();
            var typeIsMapped     = false;
            var baseTypeIsMapped = false;

            for (int i = 0; i < members.Count; i++)
            {
                var member = members[i];

                Debug.Assert(member.IdExpression == null);

                bool   isLastMember = i == members.Count - 1;
                string resolvedName = ResolveName(mappedClass, sb.ToString(), member.Name, ref type);

                /**
                 * 01.06.2020: If the name could not be resolved, then perhaps the type is not mapped? Check whether the type is in our
                 * dictionary of "base type to inherited mapping" and try it again with the type of the mappec class.
                 */
                if (string.IsNullOrEmpty(resolvedName))
                {
                    typeIsMapped     = _context.SessionFactoryContext.MappedClassMetadata.ContainsKey(type);
                    baseTypeIsMapped = _context.SessionFactoryContext.BaseClassToMappedClass.ContainsKey(type);
                    if (!typeIsMapped && baseTypeIsMapped)
                    {
                        type = _context.SessionFactoryContext.BaseClassToMappedClass[type];
                    }

                    resolvedName = ResolveName(mappedClass, sb.ToString(), member.Name, ref type);
                    if (string.IsNullOrEmpty(resolvedName))
                    {
                        throw new QueryException(String.Format(
                                                     ErrorMessages.Resolve_CannotResolveName, members[0].Name, type)
                                                 );
                    }
                }

                if (sb.Length > 0)
                {
                    sb.Append('.');
                }

                sb.Append(resolvedName);

                /**
                 * 01.06.2020: If type is not mapped, check whether the type is the base class of a mapped class.
                 * SessionFactory was extended to hold a dictionary with base type (key) and mapped class type (value). The dictionary will be used
                 * during building ICriteria if searched type is not mapped, but exists as key in this dictionary. This behavior is required if base
                 * controller classes are used and model classes are overwritten and the inherited models are mapped. If the base model are queried
                 * and filtered by name of referenced type, then the OData.nHibernate cannot find the mapping. With the new dictionary the mapping can be found.
                 */
                typeIsMapped     = _context.SessionFactoryContext.MappedClassMetadata.ContainsKey(type);
                baseTypeIsMapped = _context.SessionFactoryContext.BaseClassToMappedClass.ContainsKey(type);
                if (type != null && (typeIsMapped || baseTypeIsMapped) && !isLastMember)
                {
                    if (typeIsMapped)
                    {
                        mappedClass = _context.SessionFactoryContext.MappedClassMetadata[type];
                    }
                    else if (baseTypeIsMapped)
                    {
                        mappedClass = _context.SessionFactoryContext.MappedClassMetadata[_context.SessionFactoryContext.BaseClassToMappedClass[type]];
                    }

                    string path = (lastAliasName != null ? lastAliasName + "." : null) + sb;
                    Alias  alias;

                    if (!Aliases.TryGetValue(path, out alias))
                    {
                        alias = new Alias(_context.CreateUniqueAliasName(), path, type);
                        Aliases.Add(path, alias);
                        _context.AddAlias(alias);
                    }

                    lastAliasName = alias.Name;

                    sb.Clear();
                }
            }

            return(new ResolvedMemberExpression(
                       expression.MemberType,
                       (lastAliasName != null ? lastAliasName + "." : null) + sb,
                       type
                       ));
        }
        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 override Expression MemberExpression(MemberExpression expression)
        {
            var type = _persistentClass;
            MappedClassMetadata mappedClass = null;
            var members       = expression.Members;
            var lastAliasName = _rootAlias;

            // If we are inside a lambda expression
            if (_context.ExpressionLevel > 1)
            {
                // Lambda member expression MUST start with a variable name
                var lambdaContext = _context.FindLambdaContext(members[0].Name);
                if (lambdaContext == null)
                {
                    throw new QueryException(ErrorMessages.Expression_LambdaMemberMustStartWithParameter);
                }

                type          = lambdaContext.ParameterType;
                lastAliasName = lambdaContext.ParameterAlias;

                members = members.Skip(1).ToList();
            }
            else if (members[0].Name == "$it")
            {
                // Special case: $it variable outside of lambda expression
                members = members.Skip(1).ToList();
            }

            if (type != null)
            {
                _context.SessionFactoryContext.MappedClassMetadata.TryGetValue(type, out mappedClass);
            }

            if (members.Count == 1)
            {
                Debug.Assert(members[0].IdExpression == null);

                string resolvedName = ResolveName(mappedClass, string.Empty, members[0].Name, ref type);

                return(new ResolvedMemberExpression(
                           expression.MemberType,
                           (lastAliasName != null ? lastAliasName + "." : null) + resolvedName,
                           type
                           ));
            }

            var sb = new StringBuilder();

            for (int i = 0; i < members.Count; i++)
            {
                var member = members[i];

                Debug.Assert(member.IdExpression == null);

                bool   isLastMember = i == members.Count - 1;
                string resolvedName = ResolveName(mappedClass, sb.ToString(), member.Name, ref type);

                if (sb.Length > 0)
                {
                    sb.Append('.');
                }

                sb.Append(resolvedName);

                if (type != null && _context.SessionFactoryContext.MappedClassMetadata.ContainsKey(type) && !isLastMember)
                {
                    mappedClass = _context.SessionFactoryContext.MappedClassMetadata[type];

                    string path = (lastAliasName != null ? lastAliasName + "." : null) + sb;
                    Alias  alias;

                    if (!Aliases.TryGetValue(path, out alias))
                    {
                        alias = new Alias(_context.CreateUniqueAliasName(), path, type);
                        Aliases.Add(path, alias);
                        _context.AddAlias(alias);
                    }

                    lastAliasName = alias.Name;

                    sb.Clear();
                }
            }

            return(new ResolvedMemberExpression(
                       expression.MemberType,
                       (lastAliasName != null ? lastAliasName + "." : null) + sb,
                       type
                       ));
        }