Skip to content

Commit a0698ea

Browse files
authored
Merge pull request #249 from dmitrii-kiselev/feature/date-time-only-from-string
feat(data-reader): add support for converting `DateOnly` and `TimeOnly` types from string
2 parents 57f5908 + 580aecb commit a0698ea

File tree

2 files changed

+70
-6
lines changed

2 files changed

+70
-6
lines changed

src/EFCoreSecondLevelCacheInterceptor/EFTableRowsDataReader.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,11 +579,21 @@ public override T GetFieldValue<T>(int ordinal)
579579
return (T)(object)DateOnly.FromDateTime((DateTime)value);
580580
}
581581

582+
if (expectedValueType == TypeExtensions.DateOnlyType && actualValueType == TypeExtensions.StringType)
583+
{
584+
return (T)(object)DateOnly.Parse((string)value, CultureInfo.InvariantCulture);
585+
}
586+
582587
if (expectedValueType == TypeExtensions.TimeOnlyType && actualValueType == TypeExtensions.TimeSpanType)
583588
{
584589
return (T)(object)TimeOnly.FromTimeSpan((TimeSpan)value);
585590
}
586591

592+
if (expectedValueType == TypeExtensions.TimeOnlyType && actualValueType == TypeExtensions.StringType)
593+
{
594+
return (T)(object)TimeOnly.Parse((string)value, CultureInfo.InvariantCulture);
595+
}
596+
587597
if (expectedValueType == TypeExtensions.TimeOnlyType && isActualValueTypeNumber)
588598
{
589599
return (T)(object)TimeOnly.FromTimeSpan(new TimeSpan(Convert.ToInt64(value, CultureInfo.InvariantCulture)));

src/Tests/EFCoreSecondLevelCacheInterceptor.UnitTests/EFTableRowsDataReaderTests.cs

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1567,7 +1567,7 @@ public void GetFieldValue_ShouldReturnExpectedDateOnlyValueFromDateTime()
15671567
}
15681568

15691569
[Fact]
1570-
public void GetFieldValue__ShouldReturnExpectedDateTimeOffsetValueFromString()
1570+
public void GetFieldValue_ShouldReturnExpectedDateOnlyValueFromString()
15711571
{
15721572
// Arrange
15731573
var values = new List<object> { DateOnly.MaxValue.ToString(CultureInfo.InvariantCulture) };
@@ -1580,15 +1580,42 @@ public void GetFieldValue__ShouldReturnExpectedDateTimeOffsetValueFromString()
15801580
{ 0, new EFTableColumnInfo { DbTypeName = nameof(String), Ordinal = 0 } }
15811581
}
15821582
};
1583+
15831584
var dataReader = new EFTableRowsDataReader(tableRows);
15841585

15851586
dataReader.Read();
15861587

15871588
// Act
1588-
void Act() => dataReader.GetFieldValue<DateOnly>(0);
1589+
var actual = dataReader.GetFieldValue<DateOnly>(0);
15891590

15901591
// Assert
1591-
Assert.Throws<InvalidCastException>(Act);
1592+
Assert.Equal(DateOnly.MaxValue, actual);
1593+
}
1594+
1595+
[Fact]
1596+
public void GetFieldValue_ShouldNotThrowInvalidCastExceptionWhenValueConversionFromStringToDateOnly()
1597+
{
1598+
// Arrange
1599+
var values = new List<object> { DateOnly.MaxValue.ToString(CultureInfo.InvariantCulture) };
1600+
var tableRow = new EFTableRow(values);
1601+
var tableRows = new EFTableRows
1602+
{
1603+
Rows = new List<EFTableRow> { tableRow },
1604+
ColumnsInfo = new Dictionary<int, EFTableColumnInfo>
1605+
{
1606+
{ 0, new EFTableColumnInfo { DbTypeName = nameof(String), Ordinal = 0 } }
1607+
}
1608+
};
1609+
1610+
var dataReader = new EFTableRowsDataReader(tableRows);
1611+
1612+
dataReader.Read();
1613+
1614+
// Act
1615+
var exception = Record.Exception(() => dataReader.GetFieldValue<DateOnly>(0));
1616+
1617+
// Assert
1618+
Assert.Null(exception);
15921619
}
15931620

15941621
[Fact]
@@ -1643,6 +1670,32 @@ public void GetFieldValue_ShouldReturnExpectedTimeOnlyValueFromNumber()
16431670

16441671
[Fact]
16451672
public void GetFieldValue_ShouldReturnExpectedTimeOnlyValueFromString()
1673+
{
1674+
// Arrange
1675+
var values = new List<object> { TimeOnly.MaxValue.ToString("O", CultureInfo.InvariantCulture) };
1676+
var tableRow = new EFTableRow(values);
1677+
var tableRows = new EFTableRows
1678+
{
1679+
Rows = new List<EFTableRow> { tableRow },
1680+
ColumnsInfo = new Dictionary<int, EFTableColumnInfo>
1681+
{
1682+
{ 0, new EFTableColumnInfo { DbTypeName = nameof(String), Ordinal = 0 } }
1683+
}
1684+
};
1685+
1686+
var dataReader = new EFTableRowsDataReader(tableRows);
1687+
1688+
dataReader.Read();
1689+
1690+
// Act
1691+
var actual = dataReader.GetFieldValue<TimeOnly>(0);
1692+
1693+
// Assert
1694+
Assert.Equal(TimeOnly.MaxValue, actual);
1695+
}
1696+
1697+
[Fact]
1698+
public void GetFieldValue_ShouldNotThrowInvalidCastExceptionWhenValueConversionFromStringToTimeOnly()
16461699
{
16471700
// Arrange
16481701
var values = new List<object> { TimeOnly.MaxValue.ToString(CultureInfo.InvariantCulture) };
@@ -1652,18 +1705,19 @@ public void GetFieldValue_ShouldReturnExpectedTimeOnlyValueFromString()
16521705
Rows = new List<EFTableRow> { tableRow },
16531706
ColumnsInfo = new Dictionary<int, EFTableColumnInfo>
16541707
{
1655-
{ 0, new EFTableColumnInfo { DbTypeName = nameof(TimeSpan), Ordinal = 0 } }
1708+
{ 0, new EFTableColumnInfo { DbTypeName = nameof(String), Ordinal = 0 } }
16561709
}
16571710
};
1711+
16581712
var dataReader = new EFTableRowsDataReader(tableRows);
16591713

16601714
dataReader.Read();
16611715

16621716
// Act
1663-
void Act() => dataReader.GetFieldValue<DateOnly>(0);
1717+
var exception = Record.Exception(() => dataReader.GetFieldValue<TimeOnly>(0));
16641718

16651719
// Assert
1666-
Assert.Throws<InvalidCastException>(Act);
1720+
Assert.Null(exception);
16671721
}
16681722

16691723
[Fact]

0 commit comments

Comments
 (0)