diff --git a/src/ApiService/ApiService/onefuzzlib/orm/EntityConverter.cs b/src/ApiService/ApiService/onefuzzlib/orm/EntityConverter.cs index 04d5e5550..4141af1c2 100644 --- a/src/ApiService/ApiService/onefuzzlib/orm/EntityConverter.cs +++ b/src/ApiService/ApiService/onefuzzlib/orm/EntityConverter.cs @@ -156,16 +156,20 @@ public class EntityConverter { if (type is null) { throw new NullReferenceException(); } - var tableEntity = new TableEntity(); + var entityInfo = GetEntityInfo(); - foreach (var prop in entityInfo.properties.SelectMany(x => x)) { - //var prop = kvp.First(); + Dictionary columnValues = entityInfo.properties.SelectMany(x => x).Select(prop => { var value = entityInfo.type.GetProperty(prop.name)?.GetValue(typedEntity); + if (value == null) { + return (prop.columnName, value: (object?)null); + } if (prop.kind == EntityPropertyKind.PartitionKey || prop.kind == EntityPropertyKind.RowKey) { - tableEntity.Add(prop.columnName, value?.ToString()); - } else if (prop.type == typeof(Guid) || prop.type == typeof(Guid?)) { - tableEntity.Add(prop.columnName, value?.ToString()); - } else if (prop.type == typeof(bool) + return (prop.columnName, value?.ToString()); + } + if (prop.type == typeof(Guid) || prop.type == typeof(Guid?)) { + return (prop.columnName, value?.ToString()); + } + if (prop.type == typeof(bool) || prop.type == typeof(bool?) || prop.type == typeof(string) || prop.type == typeof(DateTime) @@ -180,19 +184,22 @@ public class EntityConverter { || prop.type == typeof(double?) ) { - tableEntity.Add(prop.columnName, value); - } else if (prop.type.IsEnum) { + return (prop.columnName, value); + } + if (prop.type.IsEnum) { var values = (value?.ToString()?.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries) .Select(CaseConverter.PascalToSnake)).EnsureNotNull($"Unable to read enum data {value}"); - tableEntity.Add(prop.columnName, string.Join(",", values)); - } else { - var serialized = JsonSerializer.Serialize(value, _options); - tableEntity.Add(prop.columnName, serialized.Trim('"')); + return (prop.columnName, string.Join(",", values)); } - } + var serialized = JsonSerializer.Serialize(value, _options); + return (prop.columnName, serialized.Trim('"')); + + }).ToDictionary(x => x.columnName, x => x.value); + + var tableEntity = new TableEntity(columnValues); if (typedEntity.ETag.HasValue) { tableEntity.ETag = typedEntity.ETag.Value; diff --git a/src/ApiService/Tests/OrmTest.cs b/src/ApiService/Tests/OrmTest.cs index c1d271de9..7e1f33381 100644 --- a/src/ApiService/Tests/OrmTest.cs +++ b/src/ApiService/Tests/OrmTest.cs @@ -330,5 +330,22 @@ namespace Tests { Assert.Equal(expectedObject, actual); } + + record TestNullField(int? Id, string? Name, TestObject? Obj) : EntityBase(); + + [Fact] + public void TestNullValue() { + + var entityConverter = new EntityConverter(); + var tableEntity = entityConverter.ToTableEntity(new TestNullField(null, null, null)); + + Assert.Null(tableEntity["id"]); + Assert.Null(tableEntity["name"]); + Assert.Null(tableEntity["obj"]); + + } + + + } }