Skip to content

Commit

Permalink
Merge branch 'release/6.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
ajcvickers committed Oct 9, 2021
2 parents 8144d50 + 938a8b0 commit 9b66f4c
Show file tree
Hide file tree
Showing 25 changed files with 126 additions and 144 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,9 @@ public static void SetPeriodEndPropertyName(this IMutableEntityType entityType,
: entityType[SqlServerAnnotationNames.TemporalHistoryTableName] is string historyTableName
? historyTableName
: entityType[SqlServerAnnotationNames.IsTemporal] as bool? == true
? entityType.ShortName() + DefaultHistoryTableNameSuffix
? entityType.GetTableName() is string tableName
? tableName + DefaultHistoryTableNameSuffix
: null
: null;

/// <summary>
Expand Down
5 changes: 2 additions & 3 deletions src/EFCore/Storage/ValueConversion/BytesToStringConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,8 @@ public BytesToStringConverter()
/// </param>
public BytesToStringConverter(ConverterMappingHints? mappingHints)
: base(
v => v == null ? null : Convert.ToBase64String(v),
v => v == null ? null : Convert.FromBase64String(v),
convertsNulls: true,
v => Convert.ToBase64String(v!),
v => Convert.FromBase64String(v!),
mappingHints)
{
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,8 @@ public IPAddressToBytesConverter()
/// </param>
public IPAddressToBytesConverter(ConverterMappingHints? mappingHints)
: base(
v => v == null ? default : v.GetAddressBytes(),
v => v == null ? default : new IPAddress(v),
convertsNulls: true,
v => v!.GetAddressBytes(),
v => new IPAddress(v!),
_defaultHints.With(mappingHints))
{
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ public IPAddressToStringConverter(ConverterMappingHints? mappingHints)
: base(
ToString(),
ToIPAddress(),
convertsNulls: true,
_defaultHints.With(mappingHints))
{
}
Expand All @@ -52,9 +51,9 @@ public IPAddressToStringConverter(ConverterMappingHints? mappingHints)
= new(typeof(IPAddress), typeof(string), i => new IPAddressToStringConverter(i.MappingHints), _defaultHints);

private new static Expression<Func<IPAddress?, string?>> ToString()
=> v => v == null ? default : v.ToString();
=> v => v!.ToString();

private static Expression<Func<string?, IPAddress?>> ToIPAddress()
=> v => v == null ? default : IPAddress.Parse(v);
=> v => IPAddress.Parse(v!);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,8 @@ public class StringNumberConverter<TModel, TProvider, TNumber> : ValueConverter<
public StringNumberConverter(
Expression<Func<TModel, TProvider>> convertToProviderExpression,
Expression<Func<TProvider, TModel>> convertFromProviderExpression,
bool convertsNulls,
ConverterMappingHints? mappingHints = null)
: base(convertToProviderExpression, convertFromProviderExpression, convertsNulls, mappingHints)
: base(convertToProviderExpression, convertFromProviderExpression, mappingHints)
{
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ public StringUriConverter(
: base(
convertToProviderExpression,
convertFromProviderExpression,
convertsNulls: true,
mappingHints)
{
}
Expand All @@ -39,7 +38,7 @@ public StringUriConverter(
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
protected new static Expression<Func<Uri?, string?>> ToString()
=> v => v != null ? v.ToString() : null;
=> v => v!.ToString();

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
Expand All @@ -48,6 +47,6 @@ public StringUriConverter(
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
protected static Expression<Func<string?, Uri?>> ToUri()
=> v => v != null ? new Uri(v, UriKind.RelativeOrAbsolute) : null;
=> v => new Uri(v!, UriKind.RelativeOrAbsolute);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ public NumberToStringConverter(ConverterMappingHints? mappingHints)
: base(
ToString(),
ToNumber(),
typeof(TNumber).IsNullableType(),
_defaultHints.With(mappingHints))
{
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,8 @@ public PhysicalAddressToBytesConverter()
/// </param>
public PhysicalAddressToBytesConverter(ConverterMappingHints? mappingHints)
: base(
v => v == null ? default : v.GetAddressBytes(),
v => v == null ? default : new PhysicalAddress(v),
convertsNulls: true,
v => v!.GetAddressBytes(),
v => new PhysicalAddress(v!),
_defaultHints.With(mappingHints))
{
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ public PhysicalAddressToStringConverter(ConverterMappingHints? mappingHints)
: base(
ToString(),
ToPhysicalAddress(),
convertsNulls: true,
_defaultHints.With(mappingHints))
{
}
Expand All @@ -54,9 +53,9 @@ public PhysicalAddressToStringConverter(ConverterMappingHints? mappingHints)
= new(typeof(PhysicalAddress), typeof(string), i => new PhysicalAddressToStringConverter(i.MappingHints), _defaultHints);

private new static Expression<Func<PhysicalAddress?, string?>> ToString()
=> v => v == null ? default! : v.ToString();
=> v => v!.ToString();

private static Expression<Func<string?, PhysicalAddress?>> ToPhysicalAddress()
=> v => v == null ? default! : PhysicalAddress.Parse(v);
=> v => PhysicalAddress.Parse(v!);
}
}
5 changes: 2 additions & 3 deletions src/EFCore/Storage/ValueConversion/StringToBytesConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,8 @@ public StringToBytesConverter(
Encoding encoding,
ConverterMappingHints? mappingHints = null)
: base(
v => v == null ? null : encoding.GetBytes(v),
v => v == null ? null : encoding.GetString(v),
convertsNulls: true,
v => encoding.GetBytes(v!),
v => encoding.GetString(v!),
mappingHints)
{
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ public StringToNumberConverter(ConverterMappingHints? mappingHints)
: base(
ToNumber(),
ToString(),
typeof(TNumber).IsNullableType(),
_defaultHints.With(mappingHints))
{
}
Expand Down
10 changes: 9 additions & 1 deletion src/EFCore/Storage/ValueConversion/ValueConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,14 @@ protected ValueConverter(
}

/// <summary>
/// Initializes a new instance of the <see cref="ValueConverter" /> class.
/// <para>
/// Initializes a new instance of the <see cref="ValueConverter" /> class, allowing conversion of
/// nulls.
/// </para>
/// <para>
/// Warning: this is currently an internal API since converting nulls to and from the database can lead to broken
/// queries and other issues. See https://github.com/dotnet/efcore/issues/26230 for more information.
/// </para>
/// </summary>
/// <remarks>
/// See <see href="https://aka.ms/efcore-docs-value-converters">EF Core value converters</see> for more information.
Expand All @@ -72,6 +79,7 @@ protected ValueConverter(
/// Hints that can be used by the <see cref="ITypeMappingSource" /> to create data types with appropriate
/// facets for the converted data.
/// </param>
[EntityFrameworkInternal]
protected ValueConverter(
LambdaExpression convertToProviderExpression,
LambdaExpression convertFromProviderExpression,
Expand Down
11 changes: 10 additions & 1 deletion src/EFCore/Storage/ValueConversion/ValueConverter`.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Internal;

namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion
Expand Down Expand Up @@ -40,7 +41,14 @@ public ValueConverter(
}

/// <summary>
/// Initializes a new instance of the <see cref="ValueConverter{TModel,TProvider}" /> class.
/// <para>
/// Initializes a new instance of the <see cref="ValueConverter{TModel,TProvider}" /> class, allowing conversion of
/// nulls.
/// </para>
/// <para>
/// Warning: this is currently an internal API since converting nulls to and from the database can lead to broken
/// queries and other issues. See https://github.com/dotnet/efcore/issues/26230 for more information.
/// </para>
/// </summary>
/// <remarks>
/// See <see href="https://aka.ms/efcore-docs-value-converters">EF Core value converters</see> for more information.
Expand All @@ -55,6 +63,7 @@ public ValueConverter(
/// Hints that can be used by the <see cref="ITypeMappingSource" /> to create data types with appropriate
/// facets for the converted data.
/// </param>
[EntityFrameworkInternal]
public ValueConverter(
Expression<Func<TModel, TProvider>> convertToProviderExpression,
Expression<Func<TProvider, TModel>> convertFromProviderExpression,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2086,7 +2086,7 @@ await Test(
Assert.Equal("Customers", table.Name);
Assert.Equal("mySchema", table.Schema);
Assert.Equal(true, table[SqlServerAnnotationNames.IsTemporal]);
Assert.Equal("CustomerHistory", table[SqlServerAnnotationNames.TemporalHistoryTableName]);
Assert.Equal("CustomersHistory", table[SqlServerAnnotationNames.TemporalHistoryTableName]);
Assert.Equal("SystemTimeStart", table[SqlServerAnnotationNames.TemporalPeriodStartPropertyName]);
Assert.Equal("SystemTimeEnd", table[SqlServerAnnotationNames.TemporalPeriodEndPropertyName]);

Expand All @@ -2109,7 +2109,7 @@ [Name] nvarchar(max) NULL,
[SystemTimeStart] datetime2 GENERATED ALWAYS AS ROW START HIDDEN NOT NULL,
CONSTRAINT [PK_Customers] PRIMARY KEY ([Id]),
PERIOD FOR SYSTEM_TIME([SystemTimeStart], [SystemTimeEnd])
) WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [mySchema].[CustomerHistory]));");
) WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [mySchema].[CustomersHistory]));");
}

[ConditionalFact]
Expand Down Expand Up @@ -2142,7 +2142,7 @@ await Test(
Assert.Equal("Customers", table.Name);
Assert.Equal("myDefaultSchema", table.Schema);
Assert.Equal(true, table[SqlServerAnnotationNames.IsTemporal]);
Assert.Equal("CustomerHistory", table[SqlServerAnnotationNames.TemporalHistoryTableName]);
Assert.Equal("CustomersHistory", table[SqlServerAnnotationNames.TemporalHistoryTableName]);
Assert.Equal("SystemTimeStart", table[SqlServerAnnotationNames.TemporalPeriodStartPropertyName]);
Assert.Equal("SystemTimeEnd", table[SqlServerAnnotationNames.TemporalPeriodEndPropertyName]);

Expand All @@ -2165,7 +2165,7 @@ [Name] nvarchar(max) NULL,
[SystemTimeStart] datetime2 GENERATED ALWAYS AS ROW START HIDDEN NOT NULL,
CONSTRAINT [PK_Customers] PRIMARY KEY ([Id]),
PERIOD FOR SYSTEM_TIME([SystemTimeStart], [SystemTimeEnd])
) WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [myDefaultSchema].[CustomerHistory]));");
) WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [myDefaultSchema].[CustomersHistory]));");
}

[ConditionalFact]
Expand Down Expand Up @@ -2198,7 +2198,7 @@ await Test(
Assert.Equal("Customers", table.Name);
Assert.Equal("mySchema", table.Schema);
Assert.Equal(true, table[SqlServerAnnotationNames.IsTemporal]);
Assert.Equal("CustomerHistory", table[SqlServerAnnotationNames.TemporalHistoryTableName]);
Assert.Equal("CustomersHistory", table[SqlServerAnnotationNames.TemporalHistoryTableName]);
Assert.Equal("SystemTimeStart", table[SqlServerAnnotationNames.TemporalPeriodStartPropertyName]);
Assert.Equal("SystemTimeEnd", table[SqlServerAnnotationNames.TemporalPeriodEndPropertyName]);

Expand All @@ -2221,7 +2221,7 @@ [Name] nvarchar(max) NULL,
[SystemTimeStart] datetime2 GENERATED ALWAYS AS ROW START HIDDEN NOT NULL,
CONSTRAINT [PK_Customers] PRIMARY KEY ([Id]),
PERIOD FOR SYSTEM_TIME([SystemTimeStart], [SystemTimeEnd])
) WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [mySchema].[CustomerHistory]));");
) WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [mySchema].[CustomersHistory]));");
}

[ConditionalFact]
Expand Down Expand Up @@ -3849,7 +3849,7 @@ [Name] nvarchar(max) NULL,
[SystemTimeStart] datetime2 GENERATED ALWAYS AS ROW START HIDDEN NOT NULL,
CONSTRAINT [PK_Customers] PRIMARY KEY ([Id]),
PERIOD FOR SYSTEM_TIME([SystemTimeStart], [SystemTimeEnd])
) WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [mySchema].[CustomerHistory]));",
) WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [mySchema].[CustomersHistory]));",
//
@"CREATE TABLE [mySchema].[Orders] (
[Id] int NOT NULL,
Expand All @@ -3858,7 +3858,7 @@ [Name] nvarchar(max) NULL,
[SystemTimeStart] datetime2 GENERATED ALWAYS AS ROW START HIDDEN NOT NULL,
CONSTRAINT [PK_Orders] PRIMARY KEY ([Id]),
PERIOD FOR SYSTEM_TIME([SystemTimeStart], [SystemTimeEnd])
) WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [mySchema].[OrderHistory]));");
) WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [mySchema].[OrdersHistory]));");
}

[ConditionalFact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,20 @@ protected override void Seed(ComplexNavigationsContext context)

ChangesDate = new DateTime(2010, 1, 1);

var historyTableInfos = new List<(string table, string historyTable)>()
var tableNames = new List<string>
{
("LevelOne", "Level1History"),
("LevelTwo", "Level2History"),
("LevelThree", "Level3History"),
("LevelFour", "Level4History"),
"LevelOne",
"LevelTwo",
"LevelThree",
"LevelFour"
};

// clean up intermittent history since in the Seed method we do fixup in multiple stages
foreach (var historyTableInfo in historyTableInfos)
foreach (var tableName in tableNames)
{
context.Database.ExecuteSqlRaw($"ALTER TABLE [{historyTableInfo.table}] SET (SYSTEM_VERSIONING = OFF)");
context.Database.ExecuteSqlRaw($"DELETE FROM [{historyTableInfo.historyTable}]");
context.Database.ExecuteSqlRaw($"ALTER TABLE [{historyTableInfo.table}] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [dbo].[{historyTableInfo.historyTable}]))");
context.Database.ExecuteSqlRaw($"ALTER TABLE [{tableName}] SET (SYSTEM_VERSIONING = OFF)");
context.Database.ExecuteSqlRaw($"DELETE FROM [{tableName + "History"}]");
context.Database.ExecuteSqlRaw($"ALTER TABLE [{tableName}] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [dbo].[{tableName + "History"}]))");
}

foreach (var entityOne in context.ChangeTracker.Entries().Where(e => e.Entity is Level1).Select(e => e.Entity))
Expand All @@ -69,16 +69,16 @@ protected override void Seed(ComplexNavigationsContext context)

context.SaveChanges();

foreach (var historyTableInfo in historyTableInfos)
foreach (var tableName in tableNames)
{
context.Database.ExecuteSqlRaw($"ALTER TABLE [{historyTableInfo.table}] SET (SYSTEM_VERSIONING = OFF)");
context.Database.ExecuteSqlRaw($"ALTER TABLE [{historyTableInfo.table}] DROP PERIOD FOR SYSTEM_TIME");
context.Database.ExecuteSqlRaw($"ALTER TABLE [{tableName}] SET (SYSTEM_VERSIONING = OFF)");
context.Database.ExecuteSqlRaw($"ALTER TABLE [{tableName}] DROP PERIOD FOR SYSTEM_TIME");

context.Database.ExecuteSqlRaw($"UPDATE [{historyTableInfo.historyTable}] SET PeriodStart = '2000-01-01T01:00:00.0000000Z'");
context.Database.ExecuteSqlRaw($"UPDATE [{historyTableInfo.historyTable}] SET PeriodEnd = '2020-07-01T07:00:00.0000000Z'");
context.Database.ExecuteSqlRaw($"UPDATE [{tableName + "History"}] SET PeriodStart = '2000-01-01T01:00:00.0000000Z'");
context.Database.ExecuteSqlRaw($"UPDATE [{tableName + "History"}] SET PeriodEnd = '2020-07-01T07:00:00.0000000Z'");

context.Database.ExecuteSqlRaw($"ALTER TABLE [{historyTableInfo.table}] ADD PERIOD FOR SYSTEM_TIME ([PeriodStart], [PeriodEnd])");
context.Database.ExecuteSqlRaw($"ALTER TABLE [{historyTableInfo.table}] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [dbo].[{historyTableInfo.historyTable}]))");
context.Database.ExecuteSqlRaw($"ALTER TABLE [{tableName}] ADD PERIOD FOR SYSTEM_TIME ([PeriodStart], [PeriodEnd])");
context.Database.ExecuteSqlRaw($"ALTER TABLE [{tableName}] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [dbo].[{tableName + "History"}]))");
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,24 +36,24 @@ protected override void Seed(InheritanceContext context)
context.RemoveRange(context.ChangeTracker.Entries().Where(e => e.Entity is Drink).Select(e => e.Entity));
context.SaveChanges();

var historyTableInfos = new List<(string table, string historyTable)>()
var tableNames = new List<string>
{
("Animals", "AnimalHistory"),
("Plants", "PlantHistory"),
("Countries", "CountryHistory"),
("Drinks", "DrinkHistory"),
"Animals",
"Plants",
"Countries",
"Drinks"
};

foreach (var historyTableInfo in historyTableInfos)
foreach (var tableName in tableNames)
{
context.Database.ExecuteSqlRaw($"ALTER TABLE [{historyTableInfo.table}] SET (SYSTEM_VERSIONING = OFF)");
context.Database.ExecuteSqlRaw($"ALTER TABLE [{historyTableInfo.table}] DROP PERIOD FOR SYSTEM_TIME");
context.Database.ExecuteSqlRaw($"ALTER TABLE [{tableName}] SET (SYSTEM_VERSIONING = OFF)");
context.Database.ExecuteSqlRaw($"ALTER TABLE [{tableName}] DROP PERIOD FOR SYSTEM_TIME");

context.Database.ExecuteSqlRaw($"UPDATE [{historyTableInfo.historyTable}] SET PeriodStart = '2000-01-01T01:00:00.0000000Z'");
context.Database.ExecuteSqlRaw($"UPDATE [{historyTableInfo.historyTable}] SET PeriodEnd = '2020-07-01T07:00:00.0000000Z'");
context.Database.ExecuteSqlRaw($"UPDATE [{tableName + "History"}] SET PeriodStart = '2000-01-01T01:00:00.0000000Z'");
context.Database.ExecuteSqlRaw($"UPDATE [{tableName + "History"}] SET PeriodEnd = '2020-07-01T07:00:00.0000000Z'");

context.Database.ExecuteSqlRaw($"ALTER TABLE [{historyTableInfo.table}] ADD PERIOD FOR SYSTEM_TIME ([PeriodStart], [PeriodEnd])");
context.Database.ExecuteSqlRaw($"ALTER TABLE [{historyTableInfo.table}] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [dbo].[{historyTableInfo.historyTable}]))");
context.Database.ExecuteSqlRaw($"ALTER TABLE [{tableName}] ADD PERIOD FOR SYSTEM_TIME ([PeriodStart], [PeriodEnd])");
context.Database.ExecuteSqlRaw($"ALTER TABLE [{tableName}] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [dbo].[{tableName + "History"}]))");
}
}
}
Expand Down
Loading

0 comments on commit 9b66f4c

Please sign in to comment.