FindLambdaContext() public method

public FindLambdaContext ( string parameterName ) : LambdaExpressionContext
parameterName string
return LambdaExpressionContext
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
                       ));
        }
        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
                       ));
        }