public IBinaryExpressionBuilder Extern(IEntityRelation relation) { var expression = (IBinaryExpressionBuilder)relation.Expression.Clone(); if (!this.Extern(relation, expression)) { throw new NotImplementedException(); } return(expression); }
/// <summary> /// Generates a relation statement. /// </summary> /// <param name="entityRelation"> /// The entity relation to generate a statement for. /// </param> /// <returns> /// The relation statement as a <see cref="string"/>. /// </returns> private string GenerateRelationStatement(IEntityRelation entityRelation) { var joinType = GetJoinClause(entityRelation.RelationType); var useAliasSuffix = string.IsNullOrWhiteSpace(this.AliasSuffix) == false; var sourceReference = this.definitionProvider.GetEntityReference(entityRelation.SourceExpression); var sourceDefinition = this.definitionProvider.Resolve(sourceReference.EntityType); var sourceAlias = entityRelation.SourceEntityAlias ?? sourceReference.EntityAlias; sourceReference.EntityAlias = useAliasSuffix ? $"{sourceAlias ?? sourceDefinition.EntityName}{this.AliasSuffix}" : sourceAlias; var sourceLocation = this.definitionProvider.GetEntityLocation(sourceReference); var sourceAttribute = this.definitionProvider.Resolve(sourceReference.EntityType) .DirectAttributes.FirstOrDefault(x => x.PropertyName == entityRelation.SourceExpression.GetPropertyName()); var sourceName = this.nameQualifier.Qualify(sourceAttribute, sourceLocation); var relationReference = this.definitionProvider.GetEntityReference(entityRelation.RelationExpression); var relationDefinition = this.definitionProvider.Resolve(relationReference.EntityType); var relationAlias = entityRelation.RelationEntityAlias ?? relationReference.EntityAlias; relationReference.EntityAlias = useAliasSuffix ? $"{relationAlias ?? relationDefinition.EntityName}{this.AliasSuffix}" : relationAlias; var relationLocation = this.definitionProvider.GetEntityLocation(relationReference); var relationAttribute = this.definitionProvider.Resolve(relationLocation.EntityType) .DirectAttributes.FirstOrDefault(x => x.PropertyName == entityRelation.RelationExpression.GetPropertyName()); var relationEntity = this.nameQualifier.GetPhysicalName(relationAttribute.Entity); var relationName = this.nameQualifier.Qualify(relationAttribute, relationLocation); if (string.IsNullOrWhiteSpace(relationLocation.Alias) && useAliasSuffix == false) { // Use the entity names for the inner join if no alias has been requested. return(string.Format( CultureInfo.InvariantCulture, RelationStatementFormat, joinType, relationEntity, sourceName, relationName)); } // Use the entity names names for the inner join and alias the table. return(string.Format( CultureInfo.InvariantCulture, AliasedRelationStatementFormat, joinType, relationEntity, this.nameQualifier.Escape(relationLocation.Alias), // TODO: could be null, need to verify sourceName, relationName)); }
/// <summary> /// Adds a relation to the selection. /// </summary> /// <param name="relation"> /// The relation to add. /// </param> /// <returns> /// The current <see cref="EntityRelationSet{T}"/>. /// </returns> private EntityRelationSet <TEntity> AddRelation([NotNull] IEntityRelation relation) { if (relation == null) { throw new ArgumentNullException(nameof(relation)); } ////if (this.entityRelations.Contains(relation) == false) ////{ this.entityRelations.Add(relation); ////} return(this); }
public string PrepareRelatedFieldDataQueries(IEntityRelation relation, IDBEntity childEntity) { if (relation.Type == EntityRelationType.ManyToMany) { var relField = relation.ParentRefField.DBName; return($@"select {childEntity.IDField} as id, {childEntity.TextField} as name, pId from {childEntity.DBName} as c1 join ( SELECT pField[s] as x, pId FROM (SELECT {relField} as pField, {_Entity.IDField} as pId, generate_subscripts({relField}, 1) AS s FROM {_Entity.DBName} where id = ANY(@ItemId) ) AS foo ) as z on c1.{childEntity.IDField} = z.x;"); } return(""); }
/// <summary> /// Builds the relation collection for a fetch of all threads with statistics. /// </summary> /// <returns>A ready to use relationcollection</returns> /// <returns>Doesn't add the thread-forum relation.</returns> internal static RelationCollection BuildRelationsForAllThreadsWithStats() { RelationCollection relations = new RelationCollection(); relations.Add(ThreadEntity.Relations.UserEntityUsingStartedByUserID, "ThreadStarterUser", JoinHint.Left); IEntityRelation threadMessage = ThreadEntity.Relations.MessageEntityUsingThreadID; // the custom filter of the relation is a subquery which compares the messageID of the last message in the thread with the messageid of the set to join threadMessage.CustomFilter = new PredicateExpression( new FieldCompareSetPredicate(MessageFields.MessageID.SetObjectAlias("LastMessage"), MessageFields.MessageID, SetOperator.Equal, (MessageFields.ThreadID == MessageFields.ThreadID.SetObjectAlias("LastMessage")), null, string.Empty, 1, new SortExpression(MessageFields.PostingDate | SortOperator.Descending))); // now add the relation to the relationcollection, we'll alias the message entity in the relation so we can refer to it in our custom filter. relations.Add(threadMessage, "LastMessage"); relations.Add(MessageEntity.Relations.UserEntityUsingPostedByUserID, "LastMessage", "LastPostingUser", JoinHint.Left); return(relations); }
protected virtual bool Extern(IEntityRelation relation, IBinaryExpressionBuilder expression) { //Nothing to do. return(true); }
/// <summary> /// Discovers the entity navigators. /// </summary> /// <param name="entitySchemaData">The entity schema data.</param> private void DiscoverEntityNavigators(EntityTypeSchemaData entitySchemaData) { var entityType = entitySchemaData.EntityType; if (entitySchemaData.Factory == null) { throw new InvalidOperationException(string.Format("Factory is null in entitySchemaData for entity '{0}'", entitySchemaData.EntityType.FullName)); } var dummyInstance = entitySchemaData.Factory.Create(); var relationsWithMappedFields = dummyInstance.GetAllRelations().Where(r => !string.IsNullOrEmpty(r.MappedFieldName) && !r.IsHierarchyRelation); var relationPerMappedFieldName = relationsWithMappedFields.ToDictionary(r => r.MappedFieldName); var properties = TypeDescriptor.GetProperties(entityType).Cast <PropertyDescriptor>(); var inheritedProperties = new HashSet <PropertyDescriptor>(DetermineInheritedProperties(entitySchemaData.EntityType, properties)); var childrenCollection = entitySchemaData.RelatedExplorerItem.Children; foreach (PropertyDescriptor property in properties) { if (!(typeof(IEntityCore).IsAssignableFrom(property.PropertyType) || typeof(IEntityCollectionCore).IsAssignableFrom(property.PropertyType))) { // not an entity navigator, continue; } string suffix = string.Empty; bool inherited = false; if (inheritedProperties.Contains(property)) { suffix = string.Format(" (Inherited from '{0}')", property.ComponentType.Name.Replace("Entity", "")); inherited = true; } // relationMapped can be null, in the case of a m:n navigator. IEntityRelation relationMapped = null; relationPerMappedFieldName.TryGetValue(property.Name, out relationMapped); if (typeof(IEntityCore).IsAssignableFrom(property.PropertyType)) { var relatedEntitySchemaData = GetEntitySchemaDataForType(property.PropertyType); // single entity navigator, or property added manually. if (relationMapped == null) { // property added manually, ignore. continue; } var icon = relationMapped.TypeOfRelation == RelationType.ManyToOne ? ExplorerIcon.ManyToOne : ExplorerIcon.OneToOne; if (inherited) { icon = ExplorerIcon.Inherited; } childrenCollection.Add(new ExplorerItem(property.Name + suffix, ExplorerItemKind.ReferenceLink, icon) { DragText = property.Name, HyperlinkTarget = relatedEntitySchemaData == null ? null : relatedEntitySchemaData.RelatedExplorerItem }); continue; } if (typeof(IEntityCollectionCore).IsAssignableFrom(property.PropertyType)) { // collection navigator. We have to determine which entity type is returned from the collection. // First, check if there's a TypeContainedAttribute on the property. If so, use the type in the attribute. If not, // try to determine the type using the linq utils method. Type containedType = null; var typeContainedAttribute = property.Attributes[typeof(TypeContainedAttribute)] as TypeContainedAttribute; if ((typeContainedAttribute != null) && typeContainedAttribute.TypeContainedInCollection != null) { containedType = typeContainedAttribute.TypeContainedInCollection; } else { containedType = LinqUtils.DetermineEntityTypeFromEntityCollectionType(property.PropertyType); } var relatedEntitySchemaData = GetEntitySchemaDataForType(containedType); var icon = relationMapped == null ? ExplorerIcon.ManyToMany : ExplorerIcon.OneToMany; if (inherited) { icon = ExplorerIcon.Inherited; } childrenCollection.Add(new ExplorerItem(property.Name + suffix, ExplorerItemKind.CollectionLink, icon) { DragText = property.Name, HyperlinkTarget = relatedEntitySchemaData == null ? null : relatedEntitySchemaData.RelatedExplorerItem }); } } }