public Task <IEnumerable <object> > GetAsync(
     IHaveSelectionSet context,
     EntityMetadataContext metadata)
 {
     return(Task.FromResult(Enumerable.Range(1, 10).Select(e =>
     {
         var instance = Activator.CreateInstance(metadata.Type);
         return instance;
     })));
 }
 public static EntityMetadataContext <T> Schema <T>(this EntityMetadataContext <T> context, string schemaName)
 {
     context.CustomMetadata.Add(Globals.CUSTOM_METADATA_SCHEMA, schemaName);
     return(context);
 }
 public static EntityMetadataContext <T> Table <T>(this EntityMetadataContext <T> context, string tableName)
 {
     context.CustomMetadata.Add(Globals.CUSTOM_METADATA_TABLE, tableName);
     return(context);
 }
Example #4
0
        private static SqlGenerationContext GenerateSQL(
            IHaveSelectionSet context,
            EntityMetadataContext metadata,
            SqlGenerationContext sqlContext = null,
            SQLOperation operation          = SQLOperation.SELECT,
            int level          = 0,
            string parentAlias = null,
            EntityMetadataRelation relationMetadata = null)
        {
            if (sqlContext == null)
            {
                sqlContext = new SqlGenerationContext();
            }

            var key = metadata.Keys.Values.ToArray();

            var schema =
                metadata.CustomMetadata.TryGetValue(Globals.CUSTOM_METADATA_SCHEMA, out var customSchema) ?
                customSchema : "dbo";

            var table =
                metadata.CustomMetadata.TryGetValue(Globals.CUSTOM_METADATA_TABLE, out var customTable) ?
                customTable : metadata.Type.Name;

            var queriedFields = context.GetSelectedFields();

            var alias = GetAlias(level);

            var entityFields =
                metadata.Included.Keys
                .Select(f => f.ToLower())
                .Intersect(queriedFields.Keys)
                .Select(f => new { field = $"{f}", exp = $"{alias}.[{f}]" })
                .ToArray();

            sqlContext.SelectFields.AddRange(entityFields);
            sqlContext.SplitOnTypes.Add(metadata.Type);
            if (level > 0)
            {
                sqlContext.SplitOnFields.Add(entityFields.First().field);
            }

            if (operation == SQLOperation.SELECT)
            {
                sqlContext.Sql = $"SELECT %fields% FROM [{schema}].[{table}] {alias}";

                foreach (var field in queriedFields)
                {
                    if (metadata.Relations.TryGetValue(field.Key.ToLower(), out var relation))
                    {
                        sqlContext.Relations.Add(relation);
                        GenerateSQL(
                            field.Value,
                            relation.EntityRight,
                            sqlContext,
                            operation: SQLOperation.JOIN,
                            level: level + 1,
                            parentAlias: alias,
                            relationMetadata: relation
                            );
                    }
                }
            }
            else if (operation == SQLOperation.JOIN)
            {
                if (relationMetadata.IsCollection)
                {
                    sqlContext.Sql += $" LEFT JOIN [{schema}].[{table}] {alias} ON {ManyForeignKeyCriteria(parentAlias, alias, relationMetadata)}";
                }
                else
                {
                    sqlContext.Sql += $" LEFT JOIN [{schema}].[{table}] {alias} ON {SingleForeignKeyCriteria(parentAlias, alias, relationMetadata)}";
                }
            }

            if (level == 0)
            {
                sqlContext.Sql = sqlContext.Sql.Replace("%fields%", string.Join(",", sqlContext.SelectFields.Select(x => x.exp)));
            }

            return(sqlContext);
        }
Example #5
0
        public async Task <IEnumerable <dynamic> > GetAsync(
            IHaveSelectionSet context,
            EntityMetadataContext metadata)
        {
            using (var connection = connectionFactory())
            {
                var sql = GenerateSQL(context, metadata);

                HashSet <object>[] mapping =
                    Enumerable.Range(1, sql.SplitOnTypes.Count())
                    .Select(x => new HashSet <object>())
                    .ToArray();

                List <dynamic>[] objectCache =
                    Enumerable.Range(1, sql.SplitOnTypes.Count())
                    .Select(x => new List <dynamic>())
                    .ToArray();

                object[] lastEntities = new dynamic[sql.SplitOnTypes.Count()];

                (await connection.QueryAsync <dynamic>(
                     sql.Sql,
                     sql.SplitOnTypes.ToArray(),
                     splitOn: string.Join(",", sql.SplitOnFields),
                     map: (entities) =>
                {
                    object result = entities[0];

                    int i = 0;
                    foreach (var entity in entities)
                    {
                        var entityKey =
                            i == 0 ?
                            metadata.PrimaryKey(entity) :
                            sql.Relations[i - 1].EntityRight.PrimaryKey(entity);

                        if (mapping[i].Contains(entityKey))
                        {
                            if (i == 0)
                            {
                                result = null;
                            }
                        }
                        else
                        {
                            if (lastEntities[i] != null)
                            {
                                if (i < objectCache.Length - 1)
                                {
                                    foreach (var obj in objectCache[i + 1])
                                    {
                                        if (sql.Relations[i].IsCollection)
                                        {
                                            sql.Relations[i].Add(lastEntities[i], obj);
                                        }
                                        else
                                        {
                                            sql.Relations[i].Set(lastEntities[i], obj);
                                        }
                                    }
                                    objectCache[i + 1].Clear();
                                    mapping[i + 1].Clear();
                                }
                            }

                            objectCache[i].Add(entity);
                            mapping[i].Add(entityKey);
                            lastEntities[i] = entity;
                        }

                        i++;
                    }

                    return(result);
                }
                     )).ToArray();

                int idx = 0;
                foreach (var entity in lastEntities)
                {
                    if (entity != null)
                    {
                        if (idx < objectCache.Length - 1)
                        {
                            foreach (var obj in objectCache[idx + 1])
                            {
                                if (sql.Relations[idx].IsCollection)
                                {
                                    sql.Relations[idx].Add(entity, obj);
                                }
                                else
                                {
                                    sql.Relations[idx].Set(entity, obj);
                                }
                            }
                            objectCache[idx + 1].Clear();
                        }
                    }
                    idx++;
                }

                return(objectCache[0]);
            }
        }