/// <summary> /// Retrieves the number of rows based on the entity and lookup condition provided. /// This method will also throw an ArgumentException if multiple rows are found in the datasource /// based on the lookup condition when the allowMultiples flag was not set. /// </summary> /// <param name="dataEntity">Data entity used to retrieve the row count.</param> /// <param name="lookupCondition">LookupCondition that is equivlent to a sql 'where' clause.</param> /// <param name="allowMultiples">Flag that identifies if multple rows may be effected by a single query.</param> /// <returns></returns> private void ValidateRowCount(DataEntity dataEntity, Expression lookupCondition, bool allowMultiples) { //create the select count (*) query var selectQuery = new SqlQueryBuilder(dataEntity, lookupCondition, Globals.QueryType.Count); //execute the the count query var queryResults = _dataAccess.Execute(selectQuery.ToString()); //retrieve the row count from the query var rowCount = Convert.ToInt32(queryResults.Rows[0][0]); //validate whether or not more than one row will be effected if (allowMultiples == false && rowCount > 1) { throw new ArgumentOutOfRangeException("allowMultiples", string.Format(ErrorCodes.TooManyRowsReturned.Description, rowCount)); } }
/// <summary> /// The Connector will perform the query and pass the results back in an /// enumerable set of ResultEntities. Each of which could be a set of objects /// </summary> /// <param name="query"></param> /// <returns></returns> public IEnumerable <DataEntity> ExecuteQuery(Query query) { // Use LogMethodExecution to add entry and exit tracing to a method. // When wrapped in a using statement, the exit point // is written during garbage collection. using (new LogMethodExecution(Globals.ConnectorName, "ExecuteQuery")) { //set the enumerated list of data entities to null IEnumerable <DataEntity> dataEntities = null; try { //Verify that a root entity is decalred and that return data is requested in the property list. if (string.IsNullOrWhiteSpace(query.RootEntity.ObjectDefinitionFullName)) { //this message can be anything that is meaningfull to the user string message = string.Format(ErrorCodes.InvalidQueryObject.Description, query.RootEntity.PropertyList.Count); //Log that no query has been filled out Logger.Write(Logger.Severity.Error, "Execute Query Failed", message); throw new ArgumentException(message); } //retrieve the name of the root entity string tableName = query.RootEntity.ObjectDefinitionFullName; //retrieve the list of column definitions for proper data type convertion DataTable columnDefinitions = _metadataAccess.GetColumnDefinitions(tableName); columnDefinitions.TableName = tableName; //Create a new instance of the query builder and send the query information along SqlQueryBuilder queryBuilder = new SqlQueryBuilder(query, columnDefinitions); //Convert the query builder to a string value string queryString = queryBuilder.ToString(); //Execute the query and retrieve the enumerated results dataEntities = _dataAccess.Execute(query.RootEntity.ObjectDefinitionFullName, queryString, queryBuilder.RelatedForeignKeys); if (dataEntities != null) { //Since the dataEntities is an enumerated list it will need to be forced to fire the execute method foreach (var entity in dataEntities) { break; } } } catch (FatalErrorException) { throw; } catch (Exception exception) { //this message may be anything that is meaningful to the user string message = string.Format("{0} {1}", ErrorCodes.GenericConnectorError, exception.Message); //Log the exception Logger.Write(Logger.Severity.Error, message, exception.StackTrace); //All exeptions that occur in the query execution must be returned as an InvalidQueryException throw new InvalidExecuteQueryException(message); } return(dataEntities); } }