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); }
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); }