示例#1
0
        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);
            }
        }
示例#2
0
        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);
        }