Description
Description
When using the LoadAsync
method on IDynamoDbContext
to load an entity using a secondary global index, I'm getting unexpected behavior: an InvalidCastException
is being thrown.
Switching the exact same call to a QueryAsync
fixes the problem.
I believe LoadAsync
is not respecting the IndexName
property on the configuration object and is using the primary index for all searches. Either the API is incredibly misleading (as it allows you to pass this unused value) or there is a bug there.
Reproduction Steps
- Create a table with a primary and a secondary index
- Map the primary key to a
Guid
property - Map the secondary key to a
string
property
[DynamoDBTable("Somethings")]
internal sealed class Something
{
[DynamoDBHashKey]
public Guid? Id { get; set; }
[DynamoDBGlobalSecondaryIndexHashKey]
public string? Name { get; set; }
}
- Try to use
LoadAsync
with astring
key and passnew DynamoDBOperationConfig { IndexName = <Name_Of_Secondary_Index> }
as options
await dynamoDBContext.LoadAsync<Something>("someName", new DynamoDBOperationConfig { IndexName = "Name-index" });
- An
InvalidCastException
is thrown - Replace the
LoadAsync
call withQueryAsync
, and it works as expected:
var query = dynamoDBContext.QueryAsync<Something>("someName", new DynamoDBOperationConfig { IndexName = "Name-index" });
await query.GetNextSetAsync();
Logs
System.InvalidCastException: Unable to cast object of type 'System.String' to type 'System.Guid'.
at Amazon.DynamoDBv2.Converter`1.TryTo(Object value, Primitive& p)
at Amazon.DynamoDBv2.Converter.TryToEntry(Object value, DynamoDBEntry& entry)
at Amazon.DynamoDBv2.Converter.ToEntry(Object value)
at Amazon.DynamoDBv2.DynamoDBEntryConversion.ConvertToEntry(Type inputType, Object value)
at Amazon.DynamoDBv2.DataModel.DynamoDBContext.ToDynamoDBEntry(SimplePropertyStorage propertyStorage, Object value, DynamoDBFlatConfig flatConfig, Boolean canReturnScalarInsteadOfList)
at Amazon.DynamoDBv2.DataModel.DynamoDBContext.ToDynamoDBEntry(SimplePropertyStorage propertyStorage, Object value, DynamoDBFlatConfig flatConfig)
at Amazon.DynamoDBv2.DataModel.DynamoDBContext.ValueToDynamoDBEntry(PropertyStorage propertyStorage, Object value, DynamoDBFlatConfig flatConfig)
at Amazon.DynamoDBv2.DataModel.DynamoDBContext.MakeKey(Object hashKey, Object rangeKey, ItemStorageConfig storageConfig, DynamoDBFlatConfig flatConfig)
at Amazon.DynamoDBv2.DataModel.DynamoDBContext.LoadHelperAsync[T](Object hashKey, Object rangeKey, DynamoDBOperationConfig operationConfig, CancellationToken cancellationToken)
at Amazon.DynamoDBv2.DataModel.DynamoDBContext.LoadAsync[T](Object hashKey, DynamoDBOperationConfig operationConfig, CancellationToken cancellationToken)
Environment
- SDK Version:
AWSSDK.Core
Version="3.5.1.39" - Package Version:
AWSSDK.DynamoDBv2
Version="3.5.3.3" - OS Info: Windows 10
- Build Environment Visual Studio 2019 16.8.1
- Targeted .NET Platform: Net Core 3.1
Resolution
- 👋 I can/would-like-to implement a fix for this problem myself
I belive LoadAsync
should be changed to respect the index being passed as a parameter and use the object hashKey
against that.
This is a 🐛 bug-report