Skip to content

Commit 08f48f0

Browse files
committed
Allow for custom property conversion
1 parent 532d332 commit 08f48f0

File tree

6 files changed

+94
-11
lines changed

6 files changed

+94
-11
lines changed

src/TableStorage.Abstractions.POCO/CalculatedKeysConverter.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,29 +12,33 @@ public class CalculatedKeysConverter<T, TPartitionKey, TRowKey> : IKeysConverter
1212
private readonly KeyMapper<T, TPartitionKey> _partitionMapper;
1313
private readonly KeyMapper<T, TRowKey> _rowMapper;
1414
private readonly JsonSerializerSettings _jsonSerializerSettings;
15+
private readonly PropertyConverters<T> _propertyConverters;
1516
private readonly Expression<Func<T, object>>[] _ignoredProperties;
1617

1718
public CalculatedKeysConverter(KeyMapper<T, TPartitionKey> partitionMapper, KeyMapper<T,TRowKey> rowMapper, JsonSerializerSettings jsonSerializerSettings,
19+
PropertyConverters<T> propertyConverters = default,
1820
params Expression<Func<T, object>>[] ignoredProperties)
1921
{
2022
_partitionMapper = partitionMapper;
2123
_rowMapper = rowMapper;
2224
_jsonSerializerSettings = jsonSerializerSettings;
25+
_propertyConverters = propertyConverters ?? new PropertyConverters<T>();
2326
_ignoredProperties = ignoredProperties;
2427
}
2528
public CalculatedKeysConverter(KeyMapper<T, TPartitionKey> partitionMapper, KeyMapper<T, TRowKey> rowMapper,
26-
params Expression<Func<T, object>>[] ignoredProperties) : this(partitionMapper, rowMapper, new JsonSerializerSettings(), ignoredProperties)
29+
PropertyConverters<T> propertyConverters = default,
30+
params Expression<Func<T, object>>[] ignoredProperties) : this(partitionMapper, rowMapper, new JsonSerializerSettings(), propertyConverters, ignoredProperties)
2731
{
2832
}
2933
public DynamicTableEntity ToEntity(T obj)
3034
{
31-
return obj.ToTableEntity(_partitionMapper.ToKey(obj), _rowMapper.ToKey(obj), _jsonSerializerSettings, _ignoredProperties);
35+
return obj.ToTableEntity(_partitionMapper.ToKey(obj), _rowMapper.ToKey(obj), _jsonSerializerSettings, _propertyConverters, _ignoredProperties);
3236
}
3337

3438
public T FromEntity(DynamicTableEntity entity)
3539
{
3640
return entity.FromTableEntity(_partitionMapper.KeyProperty, _partitionMapper.FromKey, _rowMapper.KeyProperty,
37-
_rowMapper.FromKey, _jsonSerializerSettings);
41+
_rowMapper.FromKey, _jsonSerializerSettings, _propertyConverters);
3842
}
3943

4044
public string PartitionKey(TPartitionKey key)

src/TableStorage.Abstractions.POCO/PocoTableStore.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using Newtonsoft.Json;
1212
using TableStorage.Abstractions.Models;
1313
using TableStorage.Abstractions.Store;
14+
using TableStorage.Abstractions.TableEntityConverters;
1415
using Useful.Extensions;
1516

1617
namespace TableStorage.Abstractions.POCO
@@ -40,15 +41,16 @@ namespace TableStorage.Abstractions.POCO
4041
/// or
4142
/// rowProperty</exception>
4243
public PocoTableStore(string tableName, string storageConnectionString, Expression<Func<T, object>> partitionProperty,
43-
Expression<Func<T, object>> rowProperty, PocoTableStoreOptions options = null, params Expression<Func<T, object>>[] ignoredProperties)
44+
Expression<Func<T, object>> rowProperty, PocoTableStoreOptions options = null,
45+
params Expression<Func<T, object>>[] ignoredProperties)
4446
{
4547
if (tableName == null) throw new ArgumentNullException(nameof(tableName));
4648
if (storageConnectionString == null) throw new ArgumentNullException(nameof(storageConnectionString));
4749
if (partitionProperty == null) throw new ArgumentNullException(nameof(partitionProperty));
4850
if (rowProperty == null) throw new ArgumentNullException(nameof(rowProperty));
4951

5052
options ??= new PocoTableStoreOptions();
51-
_keysConverter = new SimpleKeysConverter<T, TPartitionKey, TRowKey>(partitionProperty, rowProperty, options.JsonSerializerSettings, ignoredProperties);
53+
_keysConverter = new SimpleKeysConverter<T, TPartitionKey, TRowKey>(partitionProperty, rowProperty, options.JsonSerializerSettings, default, ignoredProperties);
5254
_tableName = tableName;
5355
_tableStore = new TableStore<DynamicTableEntity>(tableName, storageConnectionString, options.TableStorageOptions);
5456

src/TableStorage.Abstractions.POCO/SimpleKeysConverter.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,30 @@ public class SimpleKeysConverter<T, TPartitionKey, TRowKey> : IKeysConverter<T,
1111
{
1212
private readonly Expression<Func<T, object>>[] _ignoredProperties;
1313
private readonly JsonSerializerSettings _jsonSerializerSettings;
14+
private readonly PropertyConverters<T> _propertyConverters;
1415
private readonly Expression<Func<T, object>> _partitionProperty;
1516
private readonly Expression<Func<T, object>> _rowProperty;
1617

1718
public SimpleKeysConverter(Expression<Func<T, object>> partitionProperty,
18-
Expression<Func<T, object>> rowProperty, JsonSerializerSettings jsonSerializerSettings, Expression<Func<T, object>>[] ignoredProperties)
19+
Expression<Func<T, object>> rowProperty, JsonSerializerSettings jsonSerializerSettings,
20+
PropertyConverters<T> propertyConverters,
21+
Expression<Func<T, object>>[] ignoredProperties)
1922
{
2023
_partitionProperty = partitionProperty;
2124
_rowProperty = rowProperty;
2225
_ignoredProperties = ignoredProperties;
2326
_jsonSerializerSettings = jsonSerializerSettings;
27+
_propertyConverters = propertyConverters ?? new PropertyConverters<T>();
2428
}
2529

2630
public DynamicTableEntity ToEntity(T obj)
2731
{
28-
return obj.ToTableEntity(_partitionProperty, _rowProperty, _jsonSerializerSettings, _ignoredProperties);
32+
return obj.ToTableEntity(_partitionProperty, _rowProperty, _jsonSerializerSettings, _propertyConverters, _ignoredProperties);
2933
}
3034

3135
public T FromEntity(DynamicTableEntity entity)
3236
{
33-
return entity.FromTableEntity<T, TPartitionKey, TRowKey>(_partitionProperty, _rowProperty, _jsonSerializerSettings);
37+
return entity.FromTableEntity<T, TPartitionKey, TRowKey>(_partitionProperty, _rowProperty, _jsonSerializerSettings, _propertyConverters);
3438
}
3539

3640
public string PartitionKey(TPartitionKey key)

src/TableStorage.Abstractions.POCO/TableStorage.Abstractions.POCO.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
<PackageProjectUrl>https://github.com/giometrix/TableStorage.Abstractions.POCO</PackageProjectUrl>
2222
<RepositoryUrl>https://github.com/giometrix/TableStorage.Abstractions.POCO</RepositoryUrl>
2323
<PackageTags>table-storage azure-table-storage poco table-entities tableentity</PackageTags>
24-
<PackageReleaseNotes>Bug Fix: Specify DateTimeKind.UTC when timestamp is DateTime</PackageReleaseNotes>
24+
<PackageReleaseNotes>Allows for custom property conversion</PackageReleaseNotes>
2525
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
2626
<PackageLicenseExpression>MIT</PackageLicenseExpression>
2727
<PublishRepositoryUrl>true</PublishRepositoryUrl>
@@ -34,7 +34,7 @@
3434
<PackageIcon>xtensible-x.png</PackageIcon>
3535
<PackageIconUrl />
3636
<LangVersion>latest</LangVersion>
37-
<PackageVersion>3.0.1.0</PackageVersion>
37+
<PackageVersion>3.1.0.0-beta</PackageVersion>
3838
</PropertyGroup>
3939

4040
<ItemGroup>
@@ -43,7 +43,7 @@
4343
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
4444
</PackageReference>
4545
<PackageReference Include="TableStorage.Abstractions" Version="3.2.4" />
46-
<PackageReference Include="TableStorage.Abstractions.TableEntityConverters" Version="1.4.1" />
46+
<PackageReference Include="TableStorage.Abstractions.TableEntityConverters" Version="1.5.0-beta" />
4747
<PackageReference Include="Xtensible.Time.Clock" Version="1.1.0" />
4848
</ItemGroup>
4949

tests/TableStorage.Abstractions.POCO.Tests/Employee.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,9 @@ public class Employee
1010
public Department Department { get; set; }
1111
public DateTimeOffset Timestamp { get; set; }
1212
}
13+
14+
public class EmployeeWithHireDate : Employee
15+
{
16+
public DateTime HireDate { get; set; }
17+
}
1318
}

tests/TableStorage.Abstractions.POCO.Tests/PocoTableStoreTests.cs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using Microsoft.VisualStudio.TestTools.UnitTesting;
77
using Newtonsoft.Json;
88
using TableStorage.Abstractions.Store;
9+
using TableStorage.Abstractions.TableEntityConverters;
910
using Xtensible.Time;
1011

1112
namespace TableStorage.Abstractions.POCO.Tests
@@ -432,6 +433,38 @@ public void insert_record_ignore_field()
432433
var record = tableStore.GetRecord(99, 99);
433434
Assert.IsNull(record.Department);
434435
}
436+
437+
[TestMethod]
438+
public void insert_record_custom_property_converter()
439+
{
440+
var employee = new EmployeeWithHireDate
441+
{
442+
Name = "Test",
443+
CompanyId = 99,
444+
Id = 99,
445+
HireDate = new DateTime(1999,12,31),
446+
Department = new Department {Id = 5, Name = "Test"}
447+
};
448+
449+
var propertyConverters = new PropertyConverters<EmployeeWithHireDate>
450+
{
451+
[nameof(EmployeeWithHireDate.HireDate)] = new PropertyConverter<EmployeeWithHireDate>(
452+
e=>new EntityProperty(e.HireDate.ToString("yyyy-M-d")),
453+
(e,p)=>e.HireDate = DateTime.Parse(p.StringValue)
454+
)
455+
};
456+
457+
var simpleKeyConverter = new SimpleKeysConverter<EmployeeWithHireDate, int, int>(e => e.CompanyId, e => e.Id,
458+
new JsonSerializerSettings(), propertyConverters, default);
459+
460+
var tableStore = new PocoTableStore<EmployeeWithHireDate, int, int>("TestEmployee", "UseDevelopmentStorage=true",
461+
simpleKeyConverter);
462+
463+
tableStore.Insert(employee);
464+
var record = tableStore.GetRecord(99, 99);
465+
Assert.AreEqual(employee.HireDate, record.HireDate);
466+
tableStore.DeleteTable();
467+
}
435468

436469
[TestMethod]
437470
public void get_record()
@@ -1123,6 +1156,41 @@ public void insert_record_with_fixed_partition_key()
11231156
Assert.AreEqual("1", record.RowKey);
11241157
Assert.AreEqual("Mr. Jim CEO", record.Properties["Name"].StringValue);
11251158
}
1159+
1160+
[TestMethod]
1161+
public void insert_record_with_fixed_partition_key_and_custom_property_converter()
1162+
{
1163+
var employee = new EmployeeWithHireDate
1164+
{
1165+
Name = "Test",
1166+
CompanyId = 99,
1167+
Id = 99,
1168+
HireDate = new DateTime(1999,12,31),
1169+
Department = new Department {Id = 5, Name = "Test"}
1170+
};
1171+
1172+
var propertyConverters = new PropertyConverters<EmployeeWithHireDate>
1173+
{
1174+
[nameof(EmployeeWithHireDate.HireDate)] = new PropertyConverter<EmployeeWithHireDate>(
1175+
e=>new EntityProperty(e.HireDate.ToString("yyyy-M-d")),
1176+
(e,p)=>e.HireDate = DateTime.Parse(p.StringValue)
1177+
)
1178+
};
1179+
1180+
var pKeyMapper = new FixedKeyMapper<EmployeeWithHireDate, int>("SomeString");
1181+
var rKeyMapper = new KeyMapper<EmployeeWithHireDate, int>(e => e.Id.ToString(), int.Parse, e => e.Id,
1182+
id => id.ToString());
1183+
var keysConverter = new CalculatedKeysConverter<EmployeeWithHireDate, int, int>(pKeyMapper, rKeyMapper, propertyConverters: propertyConverters);
1184+
1185+
1186+
var tableStore = new PocoTableStore<EmployeeWithHireDate, int, int>("TestEmployee", "UseDevelopmentStorage=true",
1187+
keysConverter);
1188+
1189+
tableStore.Insert(employee);
1190+
var record = tableStore.GetRecord(99, 99);
1191+
Assert.AreEqual(employee.HireDate, record.HireDate);
1192+
tableStore.DeleteTable();
1193+
}
11261194

11271195
[TestMethod]
11281196
public void get_record_with_fixed_partition_key()

0 commit comments

Comments
 (0)