Skip to content

Commit

Permalink
Draft for SQL Server identity fluent API in model snapshot
Browse files Browse the repository at this point in the history
  • Loading branch information
roji committed Jun 18, 2020
1 parent 1f788de commit 9c02c00
Show file tree
Hide file tree
Showing 19 changed files with 1,239 additions and 1,026 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ public static IServiceCollection AddEntityFrameworkDesignTimeServices(
.AddSingleton<IMigrationsCodeGeneratorSelector, MigrationsCodeGeneratorSelector>()
.AddSingleton<IModelCodeGenerator, CSharpModelGenerator>()
.AddSingleton<IModelCodeGeneratorSelector, ModelCodeGeneratorSelector>()
.AddSingleton<IAnnotationCodeGenerator, AnnotationCodeGenerator>()
.AddSingleton<INamedConnectionStringResolver>(
new DesignTimeConnectionStringResolver(applicationServiceProviderAccessor))
.AddSingleton(reporter)
Expand Down
468 changes: 91 additions & 377 deletions src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,14 @@ public sealed class CSharpSnapshotGeneratorDependencies
[EntityFrameworkInternal]
public CSharpSnapshotGeneratorDependencies(
[NotNull] ICSharpHelper csharpHelper,
[NotNull] IRelationalTypeMappingSource relationalTypeMappingSource)
[NotNull] IRelationalTypeMappingSource relationalTypeMappingSource,
[NotNull] IAnnotationCodeGenerator annotationCodeGenerator)
{
Check.NotNull(csharpHelper, nameof(csharpHelper));

CSharpHelper = csharpHelper;
RelationalTypeMappingSource = relationalTypeMappingSource;
AnnotationCodeGenerator = annotationCodeGenerator;
}

/// <summary>
Expand All @@ -68,20 +70,33 @@ public CSharpSnapshotGeneratorDependencies(
/// </summary>
public IRelationalTypeMappingSource RelationalTypeMappingSource { get; }

/// <summary>
/// The annotation code generator.
/// </summary>
public IAnnotationCodeGenerator AnnotationCodeGenerator { get; }

/// <summary>
/// Clones this dependency parameter object with one service replaced.
/// </summary>
/// <param name="csharpHelper"> A replacement for the current dependency of this type. </param>
/// <returns> A new parameter object with the given service replaced. </returns>
public CSharpSnapshotGeneratorDependencies With([NotNull] ICSharpHelper csharpHelper)
=> new CSharpSnapshotGeneratorDependencies(csharpHelper, RelationalTypeMappingSource);
=> new CSharpSnapshotGeneratorDependencies(csharpHelper, RelationalTypeMappingSource, AnnotationCodeGenerator);

/// <summary>
/// Clones this dependency parameter object with one service replaced.
/// </summary>
/// <param name="relationalTypeMappingSource"> A replacement for the current dependency of this type. </param>
/// <returns> A new parameter object with the given service replaced. </returns>
public CSharpSnapshotGeneratorDependencies With([NotNull] IRelationalTypeMappingSource relationalTypeMappingSource)
=> new CSharpSnapshotGeneratorDependencies(CSharpHelper, relationalTypeMappingSource);
=> new CSharpSnapshotGeneratorDependencies(CSharpHelper, relationalTypeMappingSource, AnnotationCodeGenerator);

/// <summary>
/// Clones this dependency parameter object with one service replaced.
/// </summary>
/// <param name="annotationCodeGenerator"> A replacement for the current dependency of this type. </param>
/// <returns> A new parameter object with the given service replaced. </returns>
public CSharpSnapshotGeneratorDependencies With([NotNull] IAnnotationCodeGenerator annotationCodeGenerator)
=> new CSharpSnapshotGeneratorDependencies(CSharpHelper, RelationalTypeMappingSource, annotationCodeGenerator);
}
}
63 changes: 12 additions & 51 deletions src/EFCore.Design/Migrations/Design/MigrationsCodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.ChangeTracking.Internal;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
Expand Down Expand Up @@ -216,62 +216,23 @@ private static IEnumerable<IAnnotatable> GetAnnotatables(IModel model)
}

private IEnumerable<string> GetAnnotationNamespaces(IEnumerable<IAnnotatable> items)
{
var ignoredAnnotations = new List<string>
{
CoreAnnotationNames.NavigationCandidates,
CoreAnnotationNames.AmbiguousNavigations,
CoreAnnotationNames.InverseNavigations,
ChangeDetector.SkipDetectChangesAnnotation,
CoreAnnotationNames.OwnedTypes,
CoreAnnotationNames.ChangeTrackingStrategy,
CoreAnnotationNames.BeforeSaveBehavior,
CoreAnnotationNames.AfterSaveBehavior,
CoreAnnotationNames.TypeMapping,
CoreAnnotationNames.ValueComparer,
#pragma warning disable 618
CoreAnnotationNames.KeyValueComparer,
CoreAnnotationNames.StructuralValueComparer,
#pragma warning restore 618
CoreAnnotationNames.ConstructorBinding,
CoreAnnotationNames.NavigationAccessMode,
CoreAnnotationNames.PropertyAccessMode,
CoreAnnotationNames.ProviderClrType,
CoreAnnotationNames.ValueConverter,
CoreAnnotationNames.ValueGeneratorFactory,
CoreAnnotationNames.DefiningQuery,
CoreAnnotationNames.QueryFilter,
RelationalAnnotationNames.RelationalModel,
RelationalAnnotationNames.CheckConstraints,
RelationalAnnotationNames.Sequences,
RelationalAnnotationNames.DbFunctions,
RelationalAnnotationNames.TableMappings,
RelationalAnnotationNames.TableColumnMappings,
RelationalAnnotationNames.ViewMappings,
RelationalAnnotationNames.ViewColumnMappings,
RelationalAnnotationNames.ForeignKeyMappings,
RelationalAnnotationNames.TableIndexMappings,
RelationalAnnotationNames.UniqueConstraintMappings,
RelationalAnnotationNames.RelationalOverrides
};

return items.SelectMany(
i => i.GetAnnotations().Select(
a => new { Annotatable = i, Annotation = a })
.Where(
a => a.Annotation.Value != null
&& !ignoredAnnotations.Contains(a.Annotation.Name))
.SelectMany(a => GetProviderType(a.Annotatable, a.Annotation.Value.GetType()).GetNamespaces()));
}
=> items.SelectMany(
i =>
{
var annotations = i.GetAnnotations().ToDictionary(a => a.Name, a => a);
Dependencies.AnnotationCodeGenerator.RemoveIgnoredAnnotations(annotations);
return annotations.Values.Select(a => new { Annotatable = i, Annotation = a });
})
.SelectMany(a => GetProviderType(a.Annotatable, a.Annotation.Value.GetType()).GetNamespaces());

private ValueConverter FindValueConverter(IProperty property)
=> (property.FindTypeMapping()
?? Dependencies.RelationalTypeMappingSource.FindMapping(property))?.Converter;

private Type GetProviderType(IAnnotatable annotatable, Type valueType)
=> annotatable is IProperty property
&& valueType.UnwrapNullableType() == property.ClrType.UnwrapNullableType()
? FindValueConverter(property)?.ProviderClrType ?? valueType
: valueType;
&& valueType.UnwrapNullableType() == property.ClrType.UnwrapNullableType()
? FindValueConverter(property)?.ProviderClrType ?? valueType
: valueType;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage;

Expand Down Expand Up @@ -46,22 +47,38 @@ public sealed class MigrationsCodeGeneratorDependencies
/// </para>
/// </summary>
[EntityFrameworkInternal]
public MigrationsCodeGeneratorDependencies([NotNull] IRelationalTypeMappingSource relationalTypeMappingSource)
public MigrationsCodeGeneratorDependencies(
[NotNull] IRelationalTypeMappingSource relationalTypeMappingSource,
[NotNull] IAnnotationCodeGenerator annotationCodeGenerator)
{
RelationalTypeMappingSource = relationalTypeMappingSource;
AnnotationCodeGenerator = annotationCodeGenerator;
}

/// <summary>
/// The type mapper.
/// </summary>
public IRelationalTypeMappingSource RelationalTypeMappingSource { get; }

/// <summary>
/// The annotation code generator.
/// </summary>
public IAnnotationCodeGenerator AnnotationCodeGenerator { get; }

/// <summary>
/// Clones this dependency parameter object with one service replaced.
/// </summary>
/// <param name="relationalTypeMappingSource"> A replacement for the current dependency of this type. </param>
/// <returns> A new parameter object with the given service replaced. </returns>
public MigrationsCodeGeneratorDependencies With([NotNull] IRelationalTypeMappingSource relationalTypeMappingSource)
=> new MigrationsCodeGeneratorDependencies(relationalTypeMappingSource);
=> new MigrationsCodeGeneratorDependencies(relationalTypeMappingSource, AnnotationCodeGenerator);

/// <summary>
/// Clones this dependency parameter object with one service replaced.
/// </summary>
/// <param name="annotationCodeGenerator"> A replacement for the current dependency of this type. </param>
/// <returns> A new parameter object with the given service replaced. </returns>
public MigrationsCodeGeneratorDependencies With([NotNull] IAnnotationCodeGenerator annotationCodeGenerator)
=> new MigrationsCodeGeneratorDependencies(RelationalTypeMappingSource, annotationCodeGenerator);
}
}
Loading

0 comments on commit 9c02c00

Please sign in to comment.