/// <summary> /// Get class /// </summary> /// <typeparam name="TClass">Entity type</typeparam> /// <param name="path">Current property path</param> /// <param name="part">Class partial name</param> /// <returns>Class</returns> public TClass Class <TClass>(string path, string part, object parameters = null) { if (path == null) { throw new DataLayerException("Ошибка доступа к данным. [table alias is null] Не указано имя выходного параметра."); } if (part == null) { throw new DataLayerException("Ошибка доступа к данным. [link alias is null] Не указан алиас для подчиненного класса."); } string key = GetDataItemKey(path, part); if (IsNull(key)) { return(default(TClass)); } TClass entity = default(TClass); var reflector = _reflectors.Get <TClass>(); // If we have reflector then we will reflect entity if (reflector != null) { entity = reflector.Reflect(Value(path, part), parameters); } else { EntityMapper <TClass> mapper = _mappers.Get <TClass>(); if (mapper == null) { return(default(TClass)); } entity = mapper.TakeEntity(this, key); _cache.Add <TClass>(string.Join("#", path, part), entity); } return(entity); }
/// <summary> /// Execute query and return data map /// </summary> private IEnumerable <T> ExecuteQuery <T>(IDbCommand command, string[] outputParameters, DataAliasCollection settings, EntityMappingCollection mappings, EntityMapperCollection mappers, DataReflectorCollection reflectors, object bag) { // Get root path var rootPath = outputParameters[0]; using (var reader = command.ExecuteReader()) { var record = new DataRecord(reader, mappers, reflectors, bag); int index = 0; do { try { // Set path record.SetPath(outputParameters[index]); // Substitute stored procedure field names to manual mapped field names for (int i = 0; i < reader.FieldCount; i++) { record.AddField(settings.Get(outputParameters[index], reader.GetName(i)), i); } // Detect current iteration type if (index == 0) { // Detect primary reader for map EntityMapper <T> entityMapper = mappers.Get <T>(); if (entityMapper == null) { throw new DataLayerException(Properties.Resources.PrimaryMapperNotRegistered); } // Register types of current path in cache record.InitCache(typeof(T), typeof(List <T>), outputParameters[index]); // Read data from stream //if (reader.HasRows) while (reader.Read()) { entityMapper.ReadEntity(record, outputParameters[index]); } } else { // Take relative and ending path var relativePath = GetRelativePath(outputParameters[index]); var endingPath = GetEndingPath(outputParameters[index]); // Determine target entity type path var entityType = record.GetEntityType(relativePath); if (entityType == null) { continue; } // Take mapping var mapping = mappings.GetMapping(entityType, endingPath); if (mapping == null) { throw new DataLayerException(string.Format(Properties.Resources.MappingNotSpecified, endingPath)); } // Detect reader registered for specified path EntityMapper entityMapper = mappers.Get(mapping.ChildType); if (entityMapper == null) { continue; } // Register types of current path in cache record.InitCache(mapping.ChildType, mapping.ChildListType, outputParameters[index]); // Read data from stream and reflect it to primary entitiy //if (reader.HasRows) while (reader.Read()) { entityMapper.ReadEntity(record, outputParameters[index]); } // Taking left entities var parentEntities = record.TakeEntities(relativePath); if (parentEntities == null) { break; } // Taking child entities var childEntities = record.TakeEntities(outputParameters[index]); // Invoke join operation foreach (var parent in parentEntities) { if (!mapping.IsMatch(parent)) { continue; } List <object> result = new List <object>(); if (childEntities != null) { foreach (var child in childEntities) { if (mapping.JoinCondition(parent, child)) { result.Add(child); } } } if (result != null) { mapping.Setter(parent, result); } } } } finally { index++; } }while (reader.NextResult()); return(record.TakeEntities <T>(rootPath)); } }