Skip to content

Commit

Permalink
Fix some Timestamp/RowVersion issues.
Browse files Browse the repository at this point in the history
Still depends on dotnet/efcore#18592
Addresses PomeloFoundation#792
  • Loading branch information
lauxjpn committed Oct 25, 2019
1 parent 827adb3 commit b3c9afc
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 12 deletions.
25 changes: 21 additions & 4 deletions src/EFCore.MySql/Extensions/MySqlPropertyExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Pomelo.EntityFrameworkCore.MySql.Internal;
using Pomelo.EntityFrameworkCore.MySql.Metadata.Internal;
using Pomelo.EntityFrameworkCore.MySql.Storage.Internal;

namespace Pomelo.EntityFrameworkCore.MySql.Extensions
{
Expand Down Expand Up @@ -102,7 +105,11 @@ public static bool IsCompatibleIdentityColumn(IProperty property)
{
var type = property.ClrType;

return (type.IsInteger() || type == typeof(decimal) || type == typeof(DateTime) || type == typeof(DateTimeOffset)) && !HasConverter(property);
return (type.IsInteger()
|| type == typeof(decimal)
|| type == typeof(DateTime)
|| type == typeof(DateTimeOffset))
&& !HasConverter(property);
}

/// <summary>
Expand All @@ -114,11 +121,21 @@ public static bool IsCompatibleComputedColumn(IProperty property)
{
var type = property.ClrType;

return (type == typeof(DateTime) || type == typeof(DateTimeOffset)) && !HasConverter(property);
// RowVersion uses byte[] and the BytesToDateTimeConverter.
return (type == typeof(DateTime) || type == typeof(DateTimeOffset)) && !HasConverter(property)
|| type == typeof(byte[]) && !HasExternalConverter(property);
}

private static bool HasConverter(IProperty property)
=> (property.FindTypeMapping()?.Converter
?? property.GetValueConverter()) != null;
=> GetConverter(property) != null;

private static bool HasExternalConverter(IProperty property)
{
var converter = GetConverter(property);
return converter != null && !(converter is BytesToDateTimeConverter);
}

private static ValueConverter GetConverter(IProperty property)
=> property.FindTypeMapping()?.Converter ?? property.GetValueConverter();
}
}
5 changes: 2 additions & 3 deletions src/EFCore.MySql/Migrations/MySqlMigrationsSqlGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -561,11 +561,10 @@ protected override void Generate(
? Array.CreateInstance(clrType.GetElementType(), 0)
: clrType.GetDefaultValue());

var isRowVersion = property.ClrType == typeof(byte[])
var isRowVersion = (property.ClrType == typeof(DateTime) || property.ClrType == typeof(byte[]))
&& property.IsConcurrencyToken
&& property.ValueGenerated == ValueGenerated.OnAddOrUpdate;



var addColumnOperation = new AddColumnOperation
{
Schema = operation.Schema,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,13 @@ public class MySqlDateTimeTypeMapping : DateTimeTypeMapping
/// </summary>
public MySqlDateTimeTypeMapping(
[NotNull] string storeType,
Type clrType,
ValueConverter converter = null,
ValueComparer comparer = null,
int? precision = null)
: this(
new RelationalTypeMappingParameters(
new CoreTypeMappingParameters(typeof(DateTime), converter, comparer),
new CoreTypeMappingParameters(clrType, converter, comparer),
storeType,
precision == null ? StoreTypePostfix.None : StoreTypePostfix.Precision,
System.Data.DbType.DateTime,
Expand Down
12 changes: 8 additions & 4 deletions src/EFCore.MySql/Storage/Internal/MySqlTypeMappingSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ public class MySqlTypeMappingSource : RelationalTypeMappingSource

// DateTime
private readonly MySqlDateTypeMapping _date = new MySqlDateTypeMapping("date", DbType.Date);
private readonly MySqlDateTimeTypeMapping _dateTime6 = new MySqlDateTimeTypeMapping("datetime", precision: 6);
private readonly MySqlDateTimeTypeMapping _dateTime = new MySqlDateTimeTypeMapping("datetime");
private readonly MySqlDateTimeTypeMapping _timeStamp6 = new MySqlDateTimeTypeMapping("timestamp", precision: 6);
private readonly MySqlDateTimeTypeMapping _dateTime6 = new MySqlDateTimeTypeMapping("datetime", typeof(DateTime), precision: 6);
private readonly MySqlDateTimeTypeMapping _dateTime = new MySqlDateTimeTypeMapping("datetime", typeof(DateTime));
private readonly MySqlDateTimeTypeMapping _timeStamp6 = new MySqlDateTimeTypeMapping("timestamp", typeof(DateTime), precision: 6);
private readonly MySqlDateTimeOffsetTypeMapping _dateTimeOffset6 = new MySqlDateTimeOffsetTypeMapping("datetime", precision: 6);
private readonly MySqlDateTimeOffsetTypeMapping _dateTimeOffset = new MySqlDateTimeOffsetTypeMapping("datetime");
private readonly MySqlDateTimeOffsetTypeMapping _timeStampOffset6 = new MySqlDateTimeOffsetTypeMapping("timestamp", precision: 6);
Expand All @@ -65,11 +65,13 @@ public class MySqlTypeMappingSource : RelationalTypeMappingSource
private readonly RelationalTypeMapping _binaryRowVersion
= new MySqlDateTimeTypeMapping(
"timestamp",
typeof(byte[]),
new BytesToDateTimeConverter(),
new ByteArrayComparer());
private readonly RelationalTypeMapping _binaryRowVersion6
= new MySqlDateTimeTypeMapping(
"timestamp",
typeof(byte[]),
new BytesToDateTimeConverter(),
new ByteArrayComparer(),
precision: 6);
Expand Down Expand Up @@ -426,7 +428,9 @@ private RelationalTypeMapping FindRawMapping(RelationalTypeMappingInfo mappingIn
{
if (mappingInfo.IsRowVersion == true)
{
return _connectionInfo.ServerVersion.SupportsDateTime6 ? _binaryRowVersion6 : _binaryRowVersion;
return _connectionInfo.ServerVersion.SupportsDateTime6
? _binaryRowVersion6
: _binaryRowVersion;
}

var size = mappingInfo.Size ??
Expand Down

0 comments on commit b3c9afc

Please sign in to comment.