Пример #1
0
        internal List<Field> ExtractQueryFieldsMeta(EntityQuery query)
        {
            List<EntityRelation> relations = relMan.Read().Object;
            List<Field> result = new List<Field>();

            //split field string into tokens speparated by FIELDS_SEPARATOR
            List<string> tokens = query.Fields.Split(FIELDS_SEPARATOR).Select(x => x.Trim()).Where(x => !string.IsNullOrWhiteSpace(x)).ToList();

            //check the query tokens for widcard symbol and validate it is only that symbol - //UPDATE: allow Wildcard and field names mix. WILL NOT BE DUPLICATED
            //if (tokens.Count > 1 && tokens.Any(x => x == WILDCARD_SYMBOL))
            //	throw new Exception("Invalid query syntax. Wildcard symbol can be used only with no other fields.");

            Entity entity = entMan.ReadEntity(query.EntityName).Object;
            if (entity == null)
                throw new Exception(string.Format("The entity '{0}' does not exists.", query.EntityName));

            //We check for wildcard symbol and if present include all fields of the queried entity
            bool wildcardSelectionEnabled = tokens.Any(x => x == WILDCARD_SYMBOL);
            if (wildcardSelectionEnabled)
            {
                result.AddRange(entity.Fields);
                //return result; //UPDATE: allow Wildcard and field names mix. WILL NOT BE DUPLICATED
                tokens.Remove(WILDCARD_SYMBOL); //UPDATE: NULL Exception is triggered if not removed.
            }

            //process only tokens do not contain RELATION_SEPARATOR
            foreach (var token in tokens)
            {
                if (!token.Contains(RELATION_SEPARATOR))
                {
                    //locate the field
                    var field = entity.Fields.SingleOrDefault(x => x.Name == token);

                    //found no field for specified token
                    if (field == null)
                        throw new Exception(string.Format("Invalid query result field '{0}'. The field name is incorrect.", token));

                    //check for duplicated field tokens and ignore them
                    if (!result.Any(x => x.Id == field.Id))
                        result.Add(field);
                }
                else
                {
                    var relationData = token.Split(RELATION_SEPARATOR).Select(x => x.Trim()).Where(x => !string.IsNullOrWhiteSpace(x)).ToList();
                    if (relationData.Count > 2)
                        throw new Exception(string.Format("The specified query result  field '{0}' is incorrect. Only first level relation can be specified.", token));

                    string relationName = relationData[0];
                    string relationFieldName = relationData[1];
                    string direction = "origin-target";

                    if (string.IsNullOrWhiteSpace(relationName) || relationName == "$" || relationName == "$$")
                        throw new Exception(string.Format("Invalid relation '{0}'. The relation name is not specified.", token));
                    else if (!relationName.StartsWith("$"))
                        throw new Exception(string.Format("Invalid relation '{0}'. The relation name is not correct.", token));
                    else
                        relationName = relationName.Substring(1);

                    //check for target priority mark $$
                    if (relationName.StartsWith("$"))
                    {
                        direction = "target-origin";
                        relationName = relationName.Substring(1);
                    }

                    if (string.IsNullOrWhiteSpace(relationFieldName))
                        throw new Exception(string.Format("Invalid query result field '{0}'. The relation field name is not specified.", token));

                    Field field = result.SingleOrDefault(x => x.Name == "$" + relationName);
                    RelationFieldMeta relationFieldMeta = null;
                    if (field == null)
                    {
                        relationFieldMeta = new RelationFieldMeta();
                        relationFieldMeta.Name = "$" + relationName;
                        relationFieldMeta.Direction = direction;
                        result.Add(relationFieldMeta);
                    }
                    else
                        relationFieldMeta = (RelationFieldMeta)field;

                    relationFieldMeta.Relation = relations.SingleOrDefault(x => x.Name == relationName);
                    if (relationFieldMeta.Relation == null)
                        throw new Exception(string.Format("Invalid relation '{0}'. The relation does not exist.", token));

                    if (relationFieldMeta.Relation.TargetEntityId != entity.Id && relationFieldMeta.Relation.OriginEntityId != entity.Id)
                        throw new Exception(string.Format("Invalid relation '{0}'. The relation does relate to queries entity.", token));

                    if (relationFieldMeta.Direction != direction)
                        throw new Exception(string.Format("You are trying to query relation '{0}' from origin->target and target->origin direction in single query. This is not allowed.", token));

                    //Entity entity = entMan.ReadEntity(query.EntityName).Object;
                    relationFieldMeta.TargetEntity = entMan.ReadEntity(relationFieldMeta.Relation.TargetEntityId).Object;
                    relationFieldMeta.OriginEntity = entMan.ReadEntity(relationFieldMeta.Relation.OriginEntityId).Object;

                    //this should not happen in a perfect (no bugs) world
                    if (relationFieldMeta.OriginEntity == null)
                        throw new Exception(string.Format("Invalid query result field '{0}'. Related (origin)entity is missing.", token));
                    if (relationFieldMeta.TargetEntity == null)
                        throw new Exception(string.Format("Invalid query result field '{0}'. Related (target)entity is missing.", token));

                    relationFieldMeta.TargetField = relationFieldMeta.TargetEntity.Fields.Single(x => x.Id == relationFieldMeta.Relation.TargetFieldId);
                    relationFieldMeta.OriginField = relationFieldMeta.OriginEntity.Fields.Single(x => x.Id == relationFieldMeta.Relation.OriginFieldId);

                    //this should not happen in a perfect (no bugs) world
                    if (relationFieldMeta.OriginField == null)
                        throw new Exception(string.Format("Invalid query result field '{0}'. Related (origin)field is missing.", token));
                    if (relationFieldMeta.TargetField == null)
                        throw new Exception(string.Format("Invalid query result field '{0}'. Related (target)field is missing.", token));

                    Entity joinToEntity = null;
                    if (relationFieldMeta.TargetEntity.Id == entity.Id)
                        joinToEntity = relationFieldMeta.OriginEntity;
                    else
                        joinToEntity = relationFieldMeta.TargetEntity;

                    relationFieldMeta.Entity = joinToEntity;

                    var relatedField = joinToEntity.Fields.SingleOrDefault(x => x.Name == relationFieldName);
                    if (relatedField == null)
                        throw new Exception(string.Format("Invalid query result field '{0}'. The relation field does not exist.", token));

                    //add id field of related entity
                    if (relatedField.Name != "id")
                    {
                        var relatedIdField = joinToEntity.Fields.SingleOrDefault(x => x.Name == "id");

                        //if field already added
                        if (!relationFieldMeta.Fields.Any(x => x.Id == relatedIdField.Id))
                            relationFieldMeta.Fields.Add(relatedIdField);
                    }

                    //if field already added
                    if (relationFieldMeta.Fields.Any(x => x.Id == relatedField.Id))
                        continue;

                    relationFieldMeta.Fields.Add(relatedField);
                }
            }

            return result;
        }
Пример #2
0
        private List<Field> ExtractQueryFieldsMeta(EntityQuery query)
        {
            List<Field> result = new List<Field>();

            //split field string into tokens speparated by FIELDS_SEPARATOR
            List<string> tokens = query.Fields.Split(FIELDS_SEPARATOR).Select(x => x.Trim()).Where(x => !string.IsNullOrWhiteSpace(x)).ToList();

            //check the query tokens for widcard symbol and validate it is only that symbol
            if (tokens.Count > 1 && tokens.Any(x => x == WILDCARD_SYMBOL))
                throw new Exception("Invalid query syntax. Wildcard symbol can be used only with no other fields.");

            //get entity by name
            Entity entity = GetEntity(query.EntityName);

            if (entity == null)
                throw new Exception(string.Format("The entity '{0}' does not exists.", query.EntityName));

            //We check for wildcard symbol and if present include all fields of the queried entity
            bool wildcardSelectionEnabled = tokens.Any(x => x == WILDCARD_SYMBOL);
            if (wildcardSelectionEnabled)
            {
                result.AddRange(entity.Fields);
                return result;
            }

            //process only tokens do not contain RELATION_SEPARATOR
            foreach (var token in tokens)
            {
                if (!token.Contains(RELATION_SEPARATOR))
                {
                    //locate the field
                    var field = entity.Fields.SingleOrDefault(x => x.Name == token);

                    //found no field for specified token
                    if (field == null)
                        throw new Exception(string.Format("Invalid query result field '{0}'. The field name is incorrect.", token));

                    //check for duplicated field tokens and ignore them
                    if (!result.Any(x => x.Id == field.Id))
                        result.Add(field);
                }
                else
                {
                    var relationData = token.Split(RELATION_SEPARATOR).Select(x => x.Trim()).Where(x => !string.IsNullOrWhiteSpace(x)).ToList();
                    if (relationData.Count > 2)
                        throw new Exception(string.Format("The specified query result  field '{0}' is incorrect. Only first level relation can be specified.", token));

                    string relationName = relationData[0];
                    string relationFieldName = relationData[1];

                    if (string.IsNullOrWhiteSpace(relationName) || relationName == "$")
                        throw new Exception(string.Format("Invalid relation '{0}'. The relation name is not specified.", token));
                    else if (!relationName.StartsWith("$"))
                        throw new Exception(string.Format("Invalid relation '{0}'. The relation name is not correct.", token));
                    else
                        relationName = relationName.Substring(1);

                    if (string.IsNullOrWhiteSpace(relationFieldName))
                        throw new Exception(string.Format("Invalid query result field '{0}'. The relation field name is not specified.", token));

                    Field field = result.SingleOrDefault(x => x.Name == "$" + relationName);
                    RelationFieldMeta relationFieldMeta = null;
                    if (field == null)
                    {
                        relationFieldMeta = new RelationFieldMeta();
                        relationFieldMeta.Name = "$" + relationName;
                        result.Add(relationFieldMeta);
                    }
                    else
                        relationFieldMeta = (RelationFieldMeta)field;

                    relationFieldMeta.Relation = GetRelations().SingleOrDefault(x => x.Name == relationName);
                    if (relationFieldMeta.Relation == null)
                        throw new Exception(string.Format("Invalid relation '{0}'. The relation does not exist.", token));

                    if (relationFieldMeta.Relation.TargetEntityId != entity.Id && relationFieldMeta.Relation.OriginEntityId != entity.Id)
                        throw new Exception(string.Format("Invalid relation '{0}'. The relation does relate to queries entity.", token));

                    relationFieldMeta.TargetEntity = GetEntity(relationFieldMeta.Relation.TargetEntityId);
                    relationFieldMeta.OriginEntity = GetEntity(relationFieldMeta.Relation.OriginEntityId);

                    //this should not happen in a perfect (no bugs) world
                    if (relationFieldMeta.OriginEntity == null)
                        throw new Exception(string.Format("Invalid query result field '{0}'. Related (origin)entity is missing.", token));
                    if (relationFieldMeta.TargetEntity == null)
                        throw new Exception(string.Format("Invalid query result field '{0}'. Related (target)entity is missing.", token));

                    relationFieldMeta.TargetField = relationFieldMeta.TargetEntity.Fields.Single(x => x.Id == relationFieldMeta.Relation.TargetFieldId);
                    relationFieldMeta.OriginField = relationFieldMeta.OriginEntity.Fields.Single(x => x.Id == relationFieldMeta.Relation.OriginFieldId);

                    //this should not happen in a perfect (no bugs) world
                    if (relationFieldMeta.OriginField == null)
                        throw new Exception(string.Format("Invalid query result field '{0}'. Related (origin)field is missing.", token));
                    if (relationFieldMeta.TargetField == null)
                        throw new Exception(string.Format("Invalid query result field '{0}'. Related (target)field is missing.", token));

                    Entity joinToEntity = null;
                    if (relationFieldMeta.TargetEntity.Id == entity.Id)
                        joinToEntity = relationFieldMeta.OriginEntity;
                    else
                        joinToEntity = relationFieldMeta.TargetEntity;

                    var relatedField = joinToEntity.Fields.SingleOrDefault(x => x.Name == relationFieldName);
                    if (relatedField == null)
                        throw new Exception(string.Format("Invalid query result field '{0}'. The relation field does not exist.", token));

                    //if field already added
                    if (relationFieldMeta.Fields.Any(x => x.Id == relatedField.Id))
                        continue;

                    relationFieldMeta.Fields.Add(relatedField);
                }
            }

            return result;
        }
Пример #3
0
        private void GenerateWhereClause(QueryObject query, Entity entity, ref string sql, ref string joinSql, ref List<NpgsqlParameter> parameters,
            List<KeyValuePair<string, string>> overwriteArgs = null)
        {
            Field field = null;
            FieldType fieldType = FieldType.GuidField;
            string paramName = null;
            string completeFieldName = null;
            if (!string.IsNullOrWhiteSpace(query.FieldName))
            {
                if (!query.FieldName.Contains(RELATION_NAME_RESULT_SEPARATOR))
                {
                    field = entity.Fields.SingleOrDefault(x => x.Name == query.FieldName);
                    fieldType = field.GetFieldType();
                    string entityTablePrefix = GetTableNameForEntity(entity) + ".";
                    completeFieldName = entityTablePrefix + query.FieldName;
                    paramName = "@" + query.FieldName + "_" + Guid.NewGuid().ToString().Replace("-", "");

                    bool skipClause;
                    var value = ExtractQueryFieldValue(query.FieldValue, field, overwriteArgs, out skipClause) ?? DBNull.Value;
                    if (skipClause)
                        return;

                    parameters.Add(new NpgsqlParameter(paramName, value));
                }
                else
                {
                    var relationData = query.FieldName.Split(RELATION_SEPARATOR).Select(x => x.Trim()).Where(x => !string.IsNullOrWhiteSpace(x)).ToList();
                    if (relationData.Count > 2)
                        throw new Exception(string.Format("The specified query filter field '{0}' is incorrect. Only first level relation can be specified.", query.FieldName));

                    string relationName = relationData[0];
                    string relationFieldName = relationData[1];
                    string direction = "origin-target";

                    if (string.IsNullOrWhiteSpace(relationName) || relationName == "$" || relationName == "$$")
                        throw new Exception(string.Format("Invalid relation '{0}'. The relation name is not specified.", query.FieldName));
                    else if (!relationName.StartsWith("$"))
                        throw new Exception(string.Format("Invalid relation '{0}'. The relation name is not correct.", query.FieldName));
                    else
                        relationName = relationName.Substring(1);

                    //check for target priority mark $$
                    if (relationName.StartsWith("$"))
                    {
                        direction = "target-origin";
                        relationName = relationName.Substring(1);
                    }

                    if (string.IsNullOrWhiteSpace(relationFieldName))
                        throw new Exception(string.Format("Invalid query result field '{0}'. The relation field name is not specified.", query.FieldName));

                    RelationFieldMeta relationFieldMeta = new RelationFieldMeta();
                    relationFieldMeta.Name = "$" + relationName;
                    relationFieldMeta.Direction = direction;

                    relationFieldMeta.Relation = relMan.Read().Object.SingleOrDefault(x => x.Name == relationName);
                    if (relationFieldMeta.Relation == null)
                        throw new Exception(string.Format("Invalid relation '{0}'. The relation does not exist.", query.FieldName));

                    if (relationFieldMeta.Relation.TargetEntityId != entity.Id && relationFieldMeta.Relation.OriginEntityId != entity.Id)
                        throw new Exception(string.Format("Invalid relation '{0}'. The relation does relate to queries entity.", query.FieldName));

                    if (relationFieldMeta.Direction != direction)
                        throw new Exception(string.Format("You are trying to query relation '{0}' from origin->target and target->origin direction in single query. This is not allowed.", query.FieldName));

                    //Entity entity = entMan.ReadEntity(query.EntityName).Object;
                    relationFieldMeta.TargetEntity = entMan.ReadEntity(relationFieldMeta.Relation.TargetEntityId).Object;
                    relationFieldMeta.OriginEntity = entMan.ReadEntity(relationFieldMeta.Relation.OriginEntityId).Object;

                    //this should not happen in a perfect (no bugs) world
                    if (relationFieldMeta.OriginEntity == null)
                        throw new Exception(string.Format("Invalid query result field '{0}'. Related (origin)entity is missing.", query.FieldName));
                    if (relationFieldMeta.TargetEntity == null)
                        throw new Exception(string.Format("Invalid query result field '{0}'. Related (target)entity is missing.", query.FieldName));

                    relationFieldMeta.TargetField = relationFieldMeta.TargetEntity.Fields.Single(x => x.Id == relationFieldMeta.Relation.TargetFieldId);
                    relationFieldMeta.OriginField = relationFieldMeta.OriginEntity.Fields.Single(x => x.Id == relationFieldMeta.Relation.OriginFieldId);

                    //this should not happen in a perfect (no bugs) world
                    if (relationFieldMeta.OriginField == null)
                        throw new Exception(string.Format("Invalid query result field '{0}'. Related (origin)field is missing.", query.FieldName));
                    if (relationFieldMeta.TargetField == null)
                        throw new Exception(string.Format("Invalid query result field '{0}'. Related (target)field is missing.", query.FieldName));

                    Entity joinToEntity = null;
                    if (relationFieldMeta.TargetEntity.Id == entity.Id)
                        joinToEntity = relationFieldMeta.OriginEntity;
                    else
                        joinToEntity = relationFieldMeta.TargetEntity;

                    relationFieldMeta.Entity = joinToEntity;

                    var relatedField = joinToEntity.Fields.SingleOrDefault(x => x.Name == relationFieldName);
                    if (relatedField == null)
                        throw new Exception(string.Format("Invalid query result field '{0}'. The relation field does not exist.", query.FieldName));

                    string relationJoinSql = string.Empty;
                    completeFieldName = relationName + "." + relationFieldName;
                    fieldType = relatedField.GetFieldType();
                    paramName = "@" + relationFieldName + "_" + Guid.NewGuid().ToString().Replace("-", "");

                    bool skipClause;
                    var value = ExtractQueryFieldValue(query.FieldValue, relatedField, overwriteArgs, out skipClause) ?? DBNull.Value;
                    if (skipClause)
                        return;

                    parameters.Add(new NpgsqlParameter(paramName, value));

                    if (relationFieldMeta.Relation.RelationType == EntityRelationType.OneToOne)
                    {
                        //when the relation is origin -> target entity
                        if (relationFieldMeta.Relation.OriginEntityId == entity.Id)
                        {
                            relationJoinSql = string.Format(FILTER_JOIN,
                                GetTableNameForEntity(relationFieldMeta.TargetEntity), relationName,
                                relationName, relationFieldMeta.TargetField.Name,
                                GetTableNameForEntity(relationFieldMeta.OriginEntity), relationFieldMeta.OriginField.Name);
                        }
                        else //when the relation is target -> origin, we have to query origin entity
                        {
                            relationJoinSql = string.Format(FILTER_JOIN,
                                   GetTableNameForEntity(relationFieldMeta.OriginEntity), relationName,
                                   relationName, relationFieldMeta.OriginField.Name,
                                   GetTableNameForEntity(relationFieldMeta.TargetEntity), relationFieldMeta.TargetField.Name);
                        }
                    }
                    else if (relationFieldMeta.Relation.RelationType == EntityRelationType.OneToMany)
                    {
                        //when origin and target entity are different, then direction don't matter
                        if (relationFieldMeta.Relation.OriginEntityId != relationFieldMeta.Relation.TargetEntityId)
                        {
                            //when the relation is origin -> target entity
                            if (relationFieldMeta.Relation.OriginEntityId == entity.Id)
                            {
                                relationJoinSql = string.Format(FILTER_JOIN,
                                    GetTableNameForEntity(relationFieldMeta.TargetEntity), relationName,
                                    relationName, relationFieldMeta.TargetField.Name,
                                    GetTableNameForEntity(relationFieldMeta.OriginEntity), relationFieldMeta.OriginField.Name);
                            }
                            else //when the relation is target -> origin, we have to query origin entity
                            {
                                relationJoinSql = string.Format(FILTER_JOIN,
                                    GetTableNameForEntity(relationFieldMeta.OriginEntity), relationName,
                                    relationName, relationFieldMeta.OriginField.Name,
                                    GetTableNameForEntity(relationFieldMeta.TargetEntity), relationFieldMeta.TargetField.Name);
                            }
                        }
                        else //when the origin entity is same as target entity direction matters
                        {
                            if (relationFieldMeta.Direction == "target-origin")
                            {
                                relationJoinSql = string.Format(FILTER_JOIN,
                                   GetTableNameForEntity(relationFieldMeta.OriginEntity), relationName,
                                   relationName, relationFieldMeta.OriginField.Name,
                                   GetTableNameForEntity(relationFieldMeta.TargetEntity), relationFieldMeta.TargetField.Name);
                            }
                            else
                            {
                                relationJoinSql = string.Format(FILTER_JOIN,
                                    GetTableNameForEntity(relationFieldMeta.TargetEntity), relationName,
                                    relationName, relationFieldMeta.TargetField.Name,
                                    GetTableNameForEntity(relationFieldMeta.OriginEntity), relationFieldMeta.OriginField.Name);
                            }
                        }
                    }
                    else if (relationFieldMeta.Relation.RelationType == EntityRelationType.ManyToMany)
                    {
                        string relationTable = "rel_" + relationFieldMeta.Relation.Name;
                        string targetJoinAlias = relationName + "_target";
                        string originJoinAlias = relationName + "_origin";
                        string targetJoinTable = GetTableNameForEntity(relationFieldMeta.TargetEntity);
                        string originJoinTable = GetTableNameForEntity(relationFieldMeta.OriginEntity);

                        //if target is entity we query
                        if (entity.Id == relationFieldMeta.TargetEntity.Id)
                        {
                            relationJoinSql = string.Format(FILTER_JOIN,
                                     /*LEFT OUTER JOIN*/ relationTable, /* */ targetJoinAlias /*ON*/,
                                     targetJoinAlias, /*.*/ "target_id", /* =  */
                                     targetJoinTable, /*.*/ relationFieldMeta.TargetField.Name);

                            relationJoinSql = relationJoinSql + "\r\n" + string.Format(FILTER_JOIN,
                                    /*LEFT OUTER JOIN*/ originJoinTable, /* */ originJoinAlias /*ON*/,
                                    targetJoinAlias, /*.*/ "origin_id", /* =  */
                                    originJoinTable, /*.*/ relationFieldMeta.OriginField.Name);

                            completeFieldName = originJoinAlias + "." + relationFieldName;
                        }
                        else // if origin is entity we query
                        {
                            relationJoinSql = string.Format(FILTER_JOIN,
                                    /*LEFT OUTER JOIN*/ relationTable, /* */ originJoinAlias /*ON*/,
                                    originJoinAlias, /*.*/ "origin_id", /* =  */
                                    originJoinTable, /*.*/ relationFieldMeta.OriginField.Name);

                            relationJoinSql = relationJoinSql + "\r\n" + string.Format(FILTER_JOIN,
                                      /*LEFT OUTER JOIN*/ targetJoinTable, /* */ targetJoinAlias /*ON*/,
                                    originJoinAlias, /*.*/ "target_id", /* =  */
                                    targetJoinAlias, /*.*/ relationFieldMeta.TargetField.Name);

                            completeFieldName = targetJoinAlias + "." + relationFieldName;
                        }
                    }

                    if (!joinSql.Contains(relationJoinSql))
                        joinSql = joinSql + "\r\n" + relationJoinSql;

                }

                if ((fieldType == FieldType.MultiSelectField || fieldType == FieldType.TreeSelectField) &&
                      !(query.QueryType == QueryType.EQ || query.QueryType == QueryType.NOT))
                    throw new Exception("The query operator is not supported on field '" + fieldType.ToString() + "'");
            }

            if (sql.Length > 0)
                sql = sql + " AND ";

            switch (query.QueryType)
            {
                case QueryType.EQ:
                    {
                        //if (fieldType == FieldType.MultiSelectField)
                        //{
                        //	var parameter = parameters.Single(x => x.ParameterName == paramName);
                        //	parameter.Value = new List<string>() { (string)query.FieldValue };
                        //	sql = sql + " " + paramName + " IN ( " + completeFieldName + " )";
                        //}
                        //else if (fieldType == FieldType.TreeSelectField)
                        //{
                        //	var parameter = parameters.Single(x => x.ParameterName == paramName);
                        //	parameter.Value = new List<Guid>() { (Guid)query.FieldValue };
                        //	sql = sql + " " + paramName + " IN ( " + completeFieldName + " )";
                        //}
                        //else
                        if (query.FieldValue == null || DBNull.Value == query.FieldValue)
                            sql = sql + " " + completeFieldName + " IS NULL";
                        else
                            sql = sql + " " + completeFieldName + "=" + paramName;
                        return;
                    }
                case QueryType.NOT:
                    {
                        //if (fieldType == FieldType.MultiSelectField)
                        //{
                        //	var parameter = parameters.Single(x => x.ParameterName == paramName);
                        //	parameter.Value = new List<string>() { (string)query.FieldValue };
                        //	sql = sql + " " + paramName + " NOT IN ( " + completeFieldName + " )";
                        //}
                        //else if (fieldType == FieldType.TreeSelectField)
                        //{
                        //	var parameter = parameters.Single(x => x.ParameterName == paramName);
                        //	parameter.Value = new List<Guid>() { (Guid)query.FieldValue };
                        //	sql = sql + " " + paramName + " NOT IN ( " + completeFieldName + " )";
                        //}
                        //else
                        if (query.FieldValue == null || DBNull.Value == query.FieldValue)
                            sql = sql + " " + completeFieldName + " IS NOT NULL";
                        else
                            sql = sql + " " + completeFieldName + "<>" + paramName;

                        return;
                    }
                case QueryType.LT:
                    {
                        sql = sql + " " + completeFieldName + "<" + paramName;
                        return;
                    }
                case QueryType.LTE:
                    {
                        sql = sql + " " + completeFieldName + "<=" + paramName;
                        return;
                    }
                case QueryType.GT:
                    {
                        sql = sql + " " + completeFieldName + ">" + paramName;
                        return;
                    }
                case QueryType.GTE:
                    {
                        sql = sql + " " + completeFieldName + ">=" + paramName;
                        return;
                    }
                case QueryType.CONTAINS:
                    {
                        var parameter = parameters.Single(x => x.ParameterName == paramName);
                        parameter.Value = "%" + parameter.Value + "%";
                        sql = sql + " " + completeFieldName + " ILIKE " + paramName;
                        return;
                    }
                case QueryType.STARTSWITH:
                    {
                        var parameter = parameters.Single(x => x.ParameterName == paramName);
                        parameter.Value = parameter.Value + "%";
                        sql = sql + " " + completeFieldName + " ILIKE " + paramName;
                        return;
                    }
                case QueryType.REGEX:
                    {
                        var regexOperator = "~";
                        switch (query.RegexOperator)
                        {
                            case QueryObjectRegexOperator.MatchCaseSensitive:
                                regexOperator = "~";
                                break;
                            case QueryObjectRegexOperator.MatchCaseInsensitive:
                                regexOperator = "~*";
                                break;
                            case QueryObjectRegexOperator.DontMatchCaseSensitive:
                                regexOperator = "!~";
                                break;
                            case QueryObjectRegexOperator.DontMatchCaseInsensitive:
                                regexOperator = "!~*";
                                break;
                        }

                        sql = sql + " " + completeFieldName + " " + regexOperator + " " + paramName;
                        return;
                    }
                case QueryType.RELATED:
                    {
                        //TODO
                        throw new NotImplementedException();
                    }
                case QueryType.NOTRELATED:
                    {
                        //TODO
                        throw new NotImplementedException();
                    }
                case QueryType.AND:
                    {
                        if (query.SubQueries.Count == 1)
                            GenerateWhereClause(query.SubQueries[0], entity, ref sql, ref joinSql, ref parameters, overwriteArgs);
                        else
                        {
                            string andSql = string.Empty;
                            foreach (var q in query.SubQueries)
                            {
                                string subQuerySql = string.Empty;
                                GenerateWhereClause(q, entity, ref subQuerySql, ref joinSql, ref parameters, overwriteArgs);
                                if (andSql.Length == 0)
                                    andSql = subQuerySql;
                                else if (subQuerySql.Length > 0)
                                    andSql = andSql + " AND " + subQuerySql;
                            }

                            if (andSql.Length > 0)
                                sql = sql + " ( " + andSql + " )";
                        }
                        return;
                    }
                case QueryType.OR:
                    {
                        if (query.SubQueries.Count == 1)
                            GenerateWhereClause(query.SubQueries[0], entity, ref sql, ref joinSql, ref parameters, overwriteArgs);
                        else
                        {
                            string orSql = string.Empty;
                            foreach (var q in query.SubQueries)
                            {
                                string subQuerySql = string.Empty;
                                GenerateWhereClause(q, entity, ref subQuerySql, ref joinSql, ref parameters, overwriteArgs);
                                if (orSql.Length == 0)
                                    orSql = subQuerySql;
                                else if (subQuerySql.Length > 0)
                                    orSql = orSql + " OR " + subQuerySql;
                            }

                            if (orSql.Length > 0)
                                sql = sql + " ( " + orSql + " )";
                        }
                        return;
                    }
                default:
                    throw new Exception("Not supported query type");
            }
        }