protected override IEnumerable <Entity> ExecuteInternal(IDictionary <string, DataSource> dataSources, IQueryExecutionOptions options, IDictionary <string, Type> parameterTypes, IDictionary <string, object> parameterValues) { if (MetadataSource.HasFlag(MetadataSource.Attribute)) { if (Query.Properties == null) { Query.Properties = new MetadataPropertiesExpression(); } // Ensure the entity metadata contains the attributes if (!Query.Properties.AllProperties && !Query.Properties.PropertyNames.Contains(nameof(EntityMetadata.Attributes))) { Query.Properties.PropertyNames.Add(nameof(EntityMetadata.Attributes)); } } if (MetadataSource.HasFlag(MetadataSource.OneToManyRelationship)) { if (Query.Properties == null) { Query.Properties = new MetadataPropertiesExpression(); } // Ensure the entity metadata contains the relationships if (!Query.Properties.AllProperties && !Query.Properties.PropertyNames.Contains(nameof(EntityMetadata.OneToManyRelationships))) { Query.Properties.PropertyNames.Add(nameof(EntityMetadata.OneToManyRelationships)); } } if (MetadataSource.HasFlag(MetadataSource.ManyToOneRelationship)) { if (Query.Properties == null) { Query.Properties = new MetadataPropertiesExpression(); } // Ensure the entity metadata contains the relationships if (!Query.Properties.AllProperties && !Query.Properties.PropertyNames.Contains(nameof(EntityMetadata.ManyToOneRelationships))) { Query.Properties.PropertyNames.Add(nameof(EntityMetadata.ManyToOneRelationships)); } } if (MetadataSource.HasFlag(MetadataSource.ManyToManyRelationship)) { if (Query.Properties == null) { Query.Properties = new MetadataPropertiesExpression(); } // Ensure the entity metadata contains the relationships if (!Query.Properties.AllProperties && !Query.Properties.PropertyNames.Contains(nameof(EntityMetadata.ManyToManyRelationships))) { Query.Properties.PropertyNames.Add(nameof(EntityMetadata.ManyToManyRelationships)); } } if (!dataSources.TryGetValue(DataSource, out var dataSource)) { throw new NotSupportedQueryFragmentException("Missing datasource " + DataSource); } var resp = (RetrieveMetadataChangesResponse)dataSource.Connection.Execute(new RetrieveMetadataChangesRequest { Query = Query }); var entityProps = typeof(EntityMetadata).GetProperties().ToDictionary(p => p.Name); var oneToManyRelationshipProps = typeof(OneToManyRelationshipMetadata).GetProperties().ToDictionary(p => p.Name); var manyToManyRelationshipProps = typeof(ManyToManyRelationshipMetadata).GetProperties().ToDictionary(p => p.Name); var results = resp.EntityMetadata.Select(e => new { Entity = e, Attribute = (AttributeMetadata)null, Relationship = (RelationshipMetadataBase)null }); if (MetadataSource.HasFlag(MetadataSource.Attribute)) { results = results.SelectMany(r => r.Entity.Attributes.Select(a => new { Entity = r.Entity, Attribute = a, Relationship = r.Relationship })); } if (MetadataSource.HasFlag(MetadataSource.OneToManyRelationship)) { results = results.SelectMany(r => r.Entity.OneToManyRelationships.Select(om => new { Entity = r.Entity, Attribute = r.Attribute, Relationship = (RelationshipMetadataBase)om })); } if (MetadataSource.HasFlag(MetadataSource.ManyToOneRelationship)) { results = results.SelectMany(r => r.Entity.ManyToOneRelationships.Select(mo => new { Entity = r.Entity, Attribute = r.Attribute, Relationship = (RelationshipMetadataBase)mo })); } if (MetadataSource.HasFlag(MetadataSource.ManyToManyRelationship)) { results = results.SelectMany(r => r.Entity.ManyToManyRelationships.Where(mm => ManyToManyRelationshipJoin == null || ((string)typeof(ManyToManyRelationshipMetadata).GetProperty(ManyToManyRelationshipJoin).GetValue(mm)) == r.Entity.LogicalName).Select(mm => new { Entity = r.Entity, Attribute = r.Attribute, Relationship = (RelationshipMetadataBase)mm })); } foreach (var result in results) { var converted = new Entity(); if (MetadataSource.HasFlag(MetadataSource.Entity)) { converted.LogicalName = "entity"; converted.Id = result.Entity.MetadataId ?? Guid.Empty; foreach (var prop in _entityCols) { converted[prop.Key] = prop.Value.Accessor(result.Entity); } } if (MetadataSource.HasFlag(MetadataSource.Attribute)) { converted.LogicalName = "attribute"; converted.Id = result.Attribute.MetadataId ?? Guid.Empty; foreach (var prop in _attributeCols) { if (!prop.Value.Accessors.TryGetValue(result.Attribute.GetType(), out var accessor)) { converted[prop.Key] = SqlTypeConverter.GetNullValue(prop.Value.Type); continue; } converted[prop.Key] = accessor(result.Attribute); } } if (MetadataSource.HasFlag(MetadataSource.OneToManyRelationship)) { converted.LogicalName = "relationship_1_n"; converted.Id = result.Relationship.MetadataId ?? Guid.Empty; foreach (var prop in _oneToManyRelationshipCols) { converted[prop.Key] = prop.Value.Accessor(result.Relationship); } } if (MetadataSource.HasFlag(MetadataSource.ManyToOneRelationship)) { converted.LogicalName = "relationship_n_1"; converted.Id = result.Relationship.MetadataId ?? Guid.Empty; foreach (var prop in _manyToOneRelationshipCols) { converted[prop.Key] = prop.Value.Accessor(result.Relationship); } } if (MetadataSource.HasFlag(MetadataSource.ManyToManyRelationship)) { converted.LogicalName = "relationship_n_n"; converted.Id = result.Relationship.MetadataId ?? Guid.Empty; foreach (var prop in _manyToManyRelationshipCols) { converted[prop.Key] = prop.Value.Accessor(result.Relationship); } } yield return(converted); } }
public override INodeSchema GetSchema(IDictionary <string, DataSource> dataSources, IDictionary <string, Type> parameterTypes) { var schema = new NodeSchema(); var childCount = 0; if (MetadataSource.HasFlag(MetadataSource.Entity)) { var entityProps = (IEnumerable <MetadataProperty>)_entityProps.Values; if (Query.Properties != null) { entityProps = entityProps.Where(p => Query.Properties.AllProperties || Query.Properties.PropertyNames.Contains(p.PropertyName, StringComparer.OrdinalIgnoreCase)); } foreach (var prop in entityProps) { schema.Schema[$"{EntityAlias}.{prop.SqlName}"] = prop.Type; if (!schema.Aliases.TryGetValue(prop.SqlName, out var aliases)) { aliases = new List <string>(); schema.Aliases[prop.SqlName] = aliases; } aliases.Add($"{EntityAlias}.{prop.SqlName}"); } schema.PrimaryKey = $"{EntityAlias}.{nameof(EntityMetadata.MetadataId)}"; } if (MetadataSource.HasFlag(MetadataSource.Attribute)) { var attributeProps = (IEnumerable <AttributeProperty>)_attributeProps.Values; if (Query.AttributeQuery?.Properties != null) { attributeProps = attributeProps.Where(p => Query.AttributeQuery.Properties.AllProperties || Query.AttributeQuery.Properties.PropertyNames.Contains(p.PropertyName, StringComparer.OrdinalIgnoreCase)); } foreach (var prop in attributeProps) { schema.Schema[$"{AttributeAlias}.{prop.SqlName}"] = prop.Type; if (!schema.Aliases.TryGetValue(prop.SqlName, out var aliases)) { aliases = new List <string>(); schema.Aliases[prop.SqlName] = aliases; } aliases.Add($"{AttributeAlias}.{prop.SqlName}"); } schema.PrimaryKey = $"{AttributeAlias}.{nameof(AttributeMetadata.MetadataId)}"; childCount++; } if (MetadataSource.HasFlag(MetadataSource.OneToManyRelationship)) { var relationshipProps = (IEnumerable <MetadataProperty>)_oneToManyRelationshipProps.Values; if (Query.RelationshipQuery?.Properties != null) { relationshipProps = relationshipProps.Where(p => Query.RelationshipQuery.Properties.AllProperties || Query.RelationshipQuery.Properties.PropertyNames.Contains(p.PropertyName, StringComparer.OrdinalIgnoreCase)); } foreach (var prop in relationshipProps) { schema.Schema[$"{OneToManyRelationshipAlias}.{prop.SqlName}"] = prop.Type; if (!schema.Aliases.TryGetValue(prop.SqlName, out var aliases)) { aliases = new List <string>(); schema.Aliases[prop.SqlName] = aliases; } aliases.Add($"{OneToManyRelationshipAlias}.{prop.SqlName}"); } schema.PrimaryKey = $"{OneToManyRelationshipAlias}.{nameof(RelationshipMetadataBase.MetadataId)}"; childCount++; } if (MetadataSource.HasFlag(MetadataSource.ManyToOneRelationship)) { var relationshipProps = (IEnumerable <MetadataProperty>)_oneToManyRelationshipProps.Values; if (Query.RelationshipQuery?.Properties != null) { relationshipProps = relationshipProps.Where(p => Query.RelationshipQuery.Properties.AllProperties || Query.RelationshipQuery.Properties.PropertyNames.Contains(p.PropertyName, StringComparer.OrdinalIgnoreCase)); } foreach (var prop in relationshipProps) { schema.Schema[$"{ManyToOneRelationshipAlias}.{prop.SqlName}"] = prop.Type; if (!schema.Aliases.TryGetValue(prop.SqlName, out var aliases)) { aliases = new List <string>(); schema.Aliases[prop.SqlName] = aliases; } aliases.Add($"{ManyToOneRelationshipAlias}.{prop.SqlName}"); } schema.PrimaryKey = $"{ManyToOneRelationshipAlias}.{nameof(RelationshipMetadataBase.MetadataId)}"; childCount++; } if (MetadataSource.HasFlag(MetadataSource.ManyToManyRelationship)) { var relationshipProps = (IEnumerable <MetadataProperty>)_manyToManyRelationshipProps.Values; if (Query.RelationshipQuery?.Properties != null) { relationshipProps = relationshipProps.Where(p => Query.RelationshipQuery.Properties.AllProperties || Query.RelationshipQuery.Properties.PropertyNames.Contains(p.PropertyName, StringComparer.OrdinalIgnoreCase)); } foreach (var prop in relationshipProps) { schema.Schema[$"{ManyToManyRelationshipAlias}.{prop.SqlName}"] = prop.Type; if (!schema.Aliases.TryGetValue(prop.SqlName, out var aliases)) { aliases = new List <string>(); schema.Aliases[prop.SqlName] = aliases; } aliases.Add($"{ManyToManyRelationshipAlias}.{prop.SqlName}"); } schema.PrimaryKey = $"{ManyToManyRelationshipAlias}.{nameof(RelationshipMetadataBase.MetadataId)}"; childCount++; } if (childCount > 1) { schema.PrimaryKey = null; } return(schema); }