public override object LoadScalar(OPath.OPathQuery query) { if (query.QueryType == OPathQueryTypeEnum.Path) { query.QueryType = OPathQueryTypeEnum.Expression; query.Expression = new OPath.Expressions.Call("eval", new Evaluant.OPath.Expressions.Collections.ConstraintCollection(new OPath.Expressions.Constraint[] { query.Path })); } SqlMapperTransformer transformer = new SqlMapperTransformer(_Mapping, _Model); transformer.Dialect = Dialect; ISQLExpression exp = transformer.TransformScalar(query); _Connection.Open(); _Transaction = _Connection.BeginTransaction(); object result = null; try { string[] queries = Dialect.RenderQueries(exp); IDbCommand command = Driver.CreateCommand(queries[queries.Length - 1], _Connection, _Transaction); if (TraceSqlSwitch.Enabled) { TraceHelpler.Trace(command, _Dialect); } object res = command.ExecuteScalar(); if (res != DBNull.Value) result = res; _Transaction.Commit(); } catch { _Transaction.Rollback(); throw; } finally { _Connection.Close(); } // Ensure the result in an Int32 in case of a count() if (query.Expression.Operands[0] is OPath.Expressions.Function && ((OPath.Expressions.Function)query.Expression.Operands[0]).Type == Evaluant.OPath.Expressions.FunctionEnum.Count) result = Convert.ToInt32(result); return result; }
public override void LoadReference(IEnumerable entities, string[] references) { // references = null => don't load references if (references == null) return; // Group entities by type Hashtable orderedEntities = new Hashtable(); foreach (Entity e in entities) { if (!orderedEntities.ContainsKey(e.Type)) orderedEntities.Add(e.Type, new EntitySet()); ((EntitySet)orderedEntities[e.Type]).Add(e); e.RemoveReference(references); } // Process each entity by type foreach (string entityType in orderedEntities.Keys) { Hashtable entityIndex = new Hashtable(); foreach (Entity entity in ((EntitySet)orderedEntities[entityType])) entityIndex.Add(entity.Id, entity); string[] ids = new string[((EntitySet)orderedEntities[entityType]).Count]; int i = 0; foreach (Entity e in (EntitySet)orderedEntities[entityType]) ids[i++] = e.Id; string id = String.Join("', '", ids); Hashtable refs = GetReferenceMappings(entityType, references); // Process each reference of the current entity type foreach (string refName in refs.Keys) { ReferenceMapping rm = (ReferenceMapping)refs[refName]; Evaluant.Uss.Models.Reference referenceModel = _Model.GetReference(rm.EntityParent.Type, refName.Substring(refName.LastIndexOf('.') + 1), true); if (_Mapping.Entities[referenceModel.ParentType] == null) referenceModel = new Evaluant.Uss.Models.Reference(referenceModel.Name, entityType, referenceModel.ChildType, referenceModel.IsComposition, referenceModel.FromMany, referenceModel.ToMany); string parentType = entityType; string opath = String.Concat(parentType, "[ id( '", id, "' ) ].", refName); OPathQuery opathQuery = new OPathQuery(opath); opathQuery.Compile(); if (opathQuery.HasErrors) throw new OPathException(opathQuery); SqlMapperTransformer transformer = new SqlMapperTransformer(_Mapping, _Model); transformer.Dialect = _Dialect; string childType = referenceModel.ChildType; //StringCollection attributes = new StringCollection(); //if(_Model.GetEntity(rm.EntityChild) != null) // attributes = GetInheritedAttributes(rm.EntityChild); //string[] atts = new string[attributes.Count]; //for(i = 0; i < attributes.Count; i++) // atts[i] = attributes[i]; string[] atts = new string[0]; UnionStatement exp = (UnionStatement)transformer.TransformToSql(opathQuery.Path, atts, new string[] { }, false); // ToDo : Add expression for children types IList childrenSubTypes = _Model.GetTree(childType); foreach (SelectStatement select in exp.SelectExpressions) { EntityMapping entityChild = _Mapping.Entities[referenceModel.ChildType]; // Insert the ParentId field in case of generic reference mapping // Then, we can add the OrderBy clause for (int pmkIndex = 0; pmkIndex < rm.EntityParent.Ids.Count; pmkIndex++) { PrimaryKeyMapping pkm = rm.EntityParent.Ids[pmkIndex]; string parentIdAlias = SqlMapperTransformer.GetParentIdAlias(rm.EntityParent, pkm.Field); if (!FieldExists(select.SelectList, parentIdAlias)) select.SelectList.Insert(2 + pmkIndex, new Column(pkm, select.TableAlias, parentIdAlias, parentIdAlias)); } } if (rm.OrderBy != null && rm.OrderBy != string.Empty) { exp.OrderByClause = new OrderByClause(exp); string[] orderbies = rm.OrderBy.Split(','); foreach (string orderby in orderbies) { string[] orderbyDirection = orderby.Split(' '); if (orderbyDirection.Length == 1) exp.OrderByClause.Add(new OrderByClauseColumn(orderbyDirection[0])); else exp.OrderByClause.Add(new OrderByClauseColumn(orderbyDirection[0], orderbyDirection[1].ToLower() == "desc")); } } exp.SelectedAllColumns = true; exp.TableAlias = "q"; _Connection.Open(); _Transaction = _Connection.BeginTransaction(); try { foreach (string q in _Dialect.RenderQueries(exp, Driver)) { IDbCommand command = _Driver.CreateCommand(q, _Connection, _Transaction); if (TraceSqlSwitch.Enabled) { TraceHelpler.Trace(command, _Dialect); } using (IDataReader reader = command.ExecuteReader()) { EntityMapping entityChild = _Mapping.Entities[referenceModel.ChildType]; EntityMapping baseEntityChild = entityChild; string parentId = String.Empty; string refId = null; //String.Empty; Empty string can be the value Entity parentEntity = null, reference = null; while (reader.Read()) { string trueType = reader[SqlMapperTransformer.TYPE_ALIAS].ToString(); if (baseEntityChild == null || baseEntityChild.Type != trueType) entityChild = _Mapping.Entities[trueType]; if (entityChild == null) throw new MappingNotFoundException(string.Format("The entity [{0}] could not be found the mapping", trueType)); int nbParentIds = _Mapping.Entities[referenceModel.ParentType].Ids.Count; string[] newParentIds = new string[nbParentIds]; for (int indexId = 0; indexId < nbParentIds; indexId++) newParentIds[indexId] = reader.GetValue(reader.GetOrdinal("ParentId" + (nbParentIds == 1 ? "" : indexId.ToString()))).ToString().Trim(); string newParentId = string.Join(SqlMapperProvider.IDSEP.ToString(), newParentIds); int nbChildIds = entityChild.Ids.Count; string[] newChildIds = new string[nbChildIds]; for (int indexId = 0; indexId < nbChildIds; indexId++) { if (entityChild.Ids[indexId].Generator.Name == Evaluant.Uss.SqlMapper.GeneratorMapping.GeneratorType.business) newChildIds[indexId] = reader[entityChild.GetIdFieldAs(entityChild.Ids[indexId])].ToString().Trim(); else newChildIds[indexId] = reader.GetValue(1 + nbParentIds + indexId).ToString().Trim(); } string newReferenceId = string.Join(SqlMapperProvider.IDSEP.ToString(), newChildIds); // Go the next parent if (parentId != newParentId) { if (parentEntity != null) parentEntity.State = State.UpToDate; parentId = newParentId; parentEntity = entityIndex[parentId] as Entity; refId = null; //String.Empty; Empty string can be the value } // Create a new reference if (refId != newReferenceId) { if (reference != null) reference.State = State.UpToDate; reference = new Entity(entityChild.Type); refId = newReferenceId; reference.Id = refId; parentEntity.AddValue(refName, reference, State.UpToDate); } ImportAttributes(reader, new string[] { }, _Mapping.Entities[reference.Type], reference, transformer.ColumnAliasMapping); entityChild = baseEntityChild; } if (parentEntity != null) parentEntity.State = State.UpToDate; if (reference != null) reference.State = State.UpToDate; // mark the reference as loaded for each parentEntity foreach (Entity e in entities) if (!e.InferredReferences.Contains(refName)) e.InferredReferences.Add(refName); } } _Transaction.Commit(); } catch (Exception e) { _Transaction.Rollback(); throw e; } finally { _Connection.Close(); } } } }
public override EntitySet Load(OPathQuery query, string[] attributes, string orderby, int first, int max) { if (first <= 0) throw new ArgumentException("first must be greater than 0"); if (max < 0) throw new ArgumentException("max must be none negative"); if (max == 0 && first != 1) throw new ArgumentException("max must be greater than zero if a first index is set"); SqlMapperTransformer transformer = new SqlMapperTransformer(_Mapping, _Model); transformer.Dialect = _Dialect; ISQLExpression exp = transformer.TransformToSql((Evaluant.OPath.Expressions.Path)query.Path.Clone(), attributes, orderby == null || orderby == String.Empty ? new string[0] : orderby.Split(','), false); if (first != 1 || max != 0) { OPath.Expressions.Function countFunction = new OPath.Expressions.Function(query.Path, Evaluant.OPath.Expressions.FunctionEnum.Count); OPath.Expressions.Call callCount = new OPath.Expressions.Call("eval", new Evaluant.OPath.Expressions.Collections.ConstraintCollection(new OPath.Expressions.Constraint[] { countFunction })); query.Expression = callCount; int maxEntity = Convert.ToInt32(LoadScalar(query)); if (maxEntity < first) return new EntitySet(); // paging out of range if (max == 0) max = maxEntity; if (first + max > maxEntity) max = maxEntity - first + 1; exp = _Dialect.Page(exp, ((SelectStatement)exp).OrderByClause, first, max); } return LoadWithSql(exp, transformer.FullNameAttributes, transformer.ColumnAliasMapping, query.Path.Identifiers.Count > 1); }