I'm trying to understand how to query a table in dynamo using the DataModel. But, I found two ways that seems to work and I can't find an explanation or documentation of what's happening or if there is any difference between them.
The ways of doing it that I found is using either the Filter or the KeyExpression + FilterExpression. What is the difference and correct way of doing it?
Some examples:
Option 1:
-- With Index and Key
public async Task<List<T>> Find<T>(Guid id)
{
    var query = new QueryOperationConfig
    {
        IndexName = "Table_Id_Index",
        Filter = new QueryFilter("TableId", QueryOperator.Equal, id)
    };
    return await _dynamoDbContext
        .FromQueryAsync<T>(query)
        .GetRemainingAsync();
}
-- With Index, Key and extra filtering
public async Task<List<T>> Find<T>(Guid id)
{
    var query = new QueryOperationConfig
    {
        IndexName = "Table_Id_Index",
        Filter = new QueryFilter("TableId", QueryOperator.Equal, id)
    };
    query.AddCondition("Deleted", ScanOperator.NotEqual, true);
    return await _dynamoDbContext
        .FromQueryAsync<T>(query)
        .GetRemainingAsync();
}
-- With GSI, Key and Partion
public async Task<List<T>> Find<T>(Guid id, string partitionKey)
{
    var query = new QueryOperationConfig
    {
        IndexName = "GSI_Index",
        Filter = new QueryFilter("TableId", QueryOperator.Equal, id)
    };
    query.AddCondition("PartitionKey", QueryOperator.Equal, partitionKey);
    return await _dynamoDbContext
        .FromQueryAsync<T>(query)
        .GetRemainingAsync();
}
Option 2:
-- With Index and Key
public async Task<List<T>> Find<T>(Guid id)
{
    var expressionAttributeValues = new Dictionary<string, DynamoDBEntry>();
    expressionAttributeValues.Add(":v_TableId", id);
    var queryOperationConfig = new QueryOperationConfig
    {
        IndexName = "Table_Id_Index",
        KeyExpression = new Expression
        {
            ExpressionStatement = "TableId = :v_TableId"
            ExpressionAttributeValues = expressionAttributeValues
        }
    };
    var result = await _dynamoDBContext
        .FromQueryAsync<T>(query)
        .GetRemainingAsync();
}
-- With Index, Key and extra filtering
public async Task<List<T>> Find<T>(Guid id)
{
    var expressionAttributeValues = new Dictionary<string, DynamoDBEntry>();
    expressionAttributeValues.Add(":v_TableId", id);
    var filterAttributes = new Dictionary<string, DynamoDBEntry>();
    filterAttributes.Add(":v_Deleted", true);
    var queryOperationConfig = new QueryOperationConfig
    {
        IndexName = "Table_Id_Index",
        KeyExpression = new Expression
        {
            ExpressionStatement = "TableId = :v_TableId"
            ExpressionAttributeValues = expressionAttributeValues
        }
        FilterExpression = new Expression
        {
            ExpressionStatement = "Deleted != :v_Deleted"
            ExpressionAttributeValues = filterAttributes
        };
    };
    var result = await _dynamoDBContext
        .FromQueryAsync<T>(query)
        .GetRemainingAsync();
}
-- With GSI, Key and Partion
public async Task<List<T>> Find<T>(Guid id, string partitionKey)
{
    var expressionAttributeValues = new Dictionary<string, DynamoDBEntry>();
    expressionAttributeValues.Add(":v_TableId", id);
    expressionAttributeValues.Add(":v_PartitionKey", partitionKey);
    var queryOperationConfig = new QueryOperationConfig
    {
        IndexName = "GSI_Index",
        KeyExpression = new Expression
        {
            ExpressionStatement = "TableId = :v_TableId and PartitionKey = :v_PartitionKey"
            ExpressionAttributeValues = expressionAttributeValues
        }
    };
    var result = await _dynamoDBContext
        .FromQueryAsync<T>(query)
        .GetRemainingAsync();
}
 
    