private QueryField GetOrCreateQueryField(ColumnReferenceExpression columnReference,
                                                 bool isRepresentation, SelectPart selectPart)
        {
            var queryRoot = queryEntityTree.Get(columnReference.Table);

            if (!isRepresentation && selectPart == SelectPart.GroupBy)
            {
                QueryField fieldWithFunction;
                var        keyWithFunction = columnReference.Name + "." + true;
                if (queryRoot.fields.TryGetValue(keyWithFunction, out fieldWithFunction))
                {
                    if (fieldWithFunction.parts.Contains(SelectPart.Select))
                    {
                        isRepresentation = true;
                    }
                }
            }
            var        key = columnReference.Name + "." + isRepresentation;
            QueryField field;

            if (!queryRoot.fields.TryGetValue(key, out field))
            {
                var propertyNames    = columnReference.Name.Split('.');
                var subqueryRequired = propertyNames.Length > 1;
                var needInvert       = false;
                if (propertyNames[propertyNames.Length - 1].EqualsIgnoringCase("ЭтоГруппа"))
                {
                    needInvert       = true;
                    subqueryRequired = true;
                }
                var referencedProperties = queryEntityTree.GetProperties(queryRoot, propertyNames);
                if (isRepresentation)
                {
                    if (ReplaceWithRepresentation(referencedProperties))
                    {
                        subqueryRequired = true;
                    }
                }
                string fieldAlias = null;
                if (subqueryRequired)
                {
                    queryRoot.subqueryRequired = true;
                    fieldAlias = nameGenerator.GenerateColumnName();
                }
                foreach (var p in referencedProperties)
                {
                    p.referenced = true;
                }
                field = new QueryField(fieldAlias, referencedProperties.ToArray(), needInvert);
                queryRoot.fields.Add(key, field);
            }
            if (!field.parts.Contains(selectPart))
            {
                field.parts.Add(selectPart);
            }
            return(field);
        }
Пример #2
0
        public override ISqlElement VisitIsReference(IsReferenceExpression expression)
        {
            var queryRoot            = queryEntityRegistry.Get(expression.Argument.Table);
            var propertyNames        = expression.Argument.Name.Split('.');
            var propertiesEnumerator = new PropertiesEnumerator(propertyNames, queryRoot, queryEntityAccessor);
            var referencedProperties = propertiesEnumerator.Enumerate();

            if (referencedProperties.Count != 1)
            {
                const string messageFormat = "operator IsReference property [{0}] has many " +
                                             "variants which is not supported currently";
                throw new InvalidOperationException(string.Format(messageFormat,
                                                                  expression.Argument.Name));
            }
            var property = referencedProperties[0];
            var entity   = property.nestedEntities.SingleOrDefault(x => x.mapping.QueryTableName == expression.ObjectName);

            if (entity == null)
            {
                const string messageFormat = "can't find entity [{0}] for property [{1}]";
                throw new InvalidOperationException(string.Format(messageFormat,
                                                                  expression.ObjectName, expression.Argument.Name));
            }
            var unionCondition = queryEntityAccessor.GetUnionCondition(property, entity);

            if (unionCondition == null)
            {
                const string messageFormat = "property [{0}] has only one possible type";
                throw new InvalidOperationException(string.Format(messageFormat,
                                                                  expression.Argument.Name));
            }
            if (queryRoot.additionalFields == null)
            {
                queryRoot.additionalFields = new List <SelectFieldExpression>();
            }
            var filterColumnName = nameGenerator.GenerateColumnName();

            queryRoot.additionalFields.Add(new SelectFieldExpression
            {
                Expression = unionCondition,
                Alias      = filterColumnName
            });
            var result = new ColumnReferenceExpression
            {
                Name  = filterColumnName,
                Table = expression.Argument.Table
            };

            rewritten.Add(result);
            return(result);
        }