From 8f5e5255d53c17c82224477e4d40162adfe5ac34 Mon Sep 17 00:00:00 2001 From: Daniel Cazzulino Date: Thu, 4 Jul 2024 18:06:52 -0300 Subject: [PATCH] Fix TableEntity deserialization issue with newer Azurite We were requesting minimal metadata, and it seems they are not returning that for Timestamp anymore since v3.20.1 where this worked as-is. Added a condition to always parse as datetime for that particular property even if we don't get any metadata. --- .github/workflows/build.yml | 2 +- src/TableStorage/TableRepositoryQuery`1.cs | 11 +++++++++-- src/Tests/QueryTests.cs | 22 +++++++++++++++++++++- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9d523112..67087bc5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -66,7 +66,7 @@ jobs: - name: ⚙ azurite run: | - npm install azurite@3.20.1 + npm install azurite npx azurite & - name: 🧪 test diff --git a/src/TableStorage/TableRepositoryQuery`1.cs b/src/TableStorage/TableRepositoryQuery`1.cs index 899777cf..21dbf4e4 100644 --- a/src/TableStorage/TableRepositoryQuery`1.cs +++ b/src/TableStorage/TableRepositoryQuery`1.cs @@ -267,6 +267,12 @@ static Dictionary JsonElementToDictionary(JsonElement element) dictionary.Add(property.Name, long.Parse(value, CultureInfo.InvariantCulture)); continue; } + } + else if (property.Name == nameof(ITableEntity.Timestamp)) + { + // Reading from Azure SDK will always return DateTimeOffset for dates, instead of date time. + dictionary.Add(property.Name, DateTimeOffset.Parse(value, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind)); + continue; } dictionary.Add(property.Name, value); @@ -316,9 +322,10 @@ protected override Expression VisitMethodCall(MethodCallExpression node) { if (node.Method.Name == "get_Item" && node.Method.GetParameters() is var parameters && parameters.Length == 1 && - node.Arguments[0] is ConstantExpression constant) + node.Arguments[0] is ConstantExpression constant && + constant.Value is string value) { - Properties.Add((string)constant.Value); + Properties.Add(value); } return node; diff --git a/src/Tests/QueryTests.cs b/src/Tests/QueryTests.cs index ced5e352..9b33d0d8 100644 --- a/src/Tests/QueryTests.cs +++ b/src/Tests/QueryTests.cs @@ -173,6 +173,26 @@ public async Task EnumFailsInTableClient() // .ToList()); } + [Fact] + public async Task CanQueryWithAndWithoutFilter() + { + var repo = TableRepository.Create(CloudStorageAccount.DevelopmentStorageAccount, "test2"); + await repo.PutAsync(new TableEntity("partition", "row") + { + { "foo", "bar" } + }); + + await foreach (var item in repo.CreateQuery().Where(x => x.PartitionKey == "foo")) + { + Assert.NotNull(item.Timestamp); + } + + await foreach (var item in repo.CreateQuery()) + { + Assert.NotNull(item.Timestamp); + } + } + [Fact] public async Task CanFilterByEntityRowKey() { @@ -194,7 +214,7 @@ public async Task CanFilterByEntityRowKey() Assert.NotEmpty(entity.PartitionKey); Assert.NotEmpty(entity.RowKey); Assert.NotEqual(default(ETag), entity.ETag); - Assert.NotEqual(DateTime.MinValue, entity.Timestamp); + Assert.NotNull(entity.Timestamp); var projection = from book in repo.CreateQuery() where