public virtual void AddConditions(IDynamoCommonQuery dynamoQ, IDataQuery q) { if (q.Conditions.Count == 0) { return; } var dbConditions = new List <DataConditionExpression>(); var args = new Dictionary <string, object>(); var sb = StringBuilderCache.Allocate(); var isMultipleWithOrTerm = q.Conditions.Any(x => x.Term == QueryTerm.Or) && q.Conditions.Count > 1; foreach (var condition in q.Conditions) { var fmt = DynamoQueryConditions.GetExpressionFormat(condition.QueryCondition.Alias); var multiFmt = DynamoQueryConditions.GetMultiExpressionFormat(condition.QueryCondition.Alias); if (fmt == null && multiFmt == null && isMultipleWithOrTerm) { throw new NotSupportedException( $"DynamoDB does not support {condition.QueryCondition.Alias} filter with multiple OR queries"); } if (fmt == null && multiFmt == null) { continue; } dbConditions.Add(condition); if (sb.Length > 0) { sb.Append(condition.Term == QueryTerm.Or ? " OR " : " AND "); } if (fmt != null) { var pId = "p" + args.Count; args[pId] = condition.Value; sb.Append(string.Format(fmt, dynamoQ.GetFieldLabel(condition.Field.Name), ":" + pId)); } else { var multiExpr = GetMultiConditionExpression(dynamoQ, condition, multiFmt, args); sb.Append(multiExpr); } } var filter = StringBuilderCache.Retrieve(sb); if (filter.Length > 0) { dynamoQ.AddFilter(filter, args); } q.Conditions.RemoveAll(dbConditions.Contains); }
public virtual string GetMultiConditionExpression(IDynamoCommonQuery dynamoQ, DataConditionExpression condition, string multiFmt, Dictionary <string, object> args, string argPrefix = "p") { if (multiFmt == null) { return(null); } if (condition.QueryCondition.Alias == ConditionAlias.Between) { var values = ((IEnumerable)condition.Value).Map(x => x); if (values.Count < 2) { throw new ArgumentException($"{condition.Field.Name} BETWEEN must have 2 values"); } var pFrom = argPrefix + args.Count; args[pFrom] = values[0]; var pTo = argPrefix + args.Count; args[pTo] = values[1]; return(string.Format(multiFmt, dynamoQ.GetFieldLabel(condition.Field.Name), ":" + pFrom, ":" + pTo)); } else { var values = (IEnumerable)condition.Value; var sbIn = StringBuilderCache.Allocate(); foreach (var value in values) { if (sbIn.Length > 0) { sbIn.Append(","); } var pArg = argPrefix + args.Count; args[pArg] = value; sbIn.Append(":" + pArg); } return(string.Format(multiFmt, dynamoQ.GetFieldLabel(condition.Field.Name), StringBuilderCache.Retrieve(sbIn))); } }