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