Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Further merge query types into entity types #17101

Merged
merged 1 commit into from
Aug 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public virtual void Generate(string builderName, IModel model, IndentedStringBui
stringBuilder.AppendLine(";");
}

GenerateEntityTypes(builderName, Sort(model.GetEntityTypes().Where(et => et.FindPrimaryKey() != null).ToList()), stringBuilder);
GenerateEntityTypes(builderName, Sort(model.GetEntityTypes().Where(et => !et.MigrationsIgnored()).ToList()), stringBuilder);
}

private static IReadOnlyList<IEntityType> Sort(IReadOnlyList<IEntityType> entityTypes)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -360,8 +360,10 @@ private void GenerateEntityType(IEntityType entityType, bool useDataAnnotations)
RemoveAnnotation(ref annotations, RelationalAnnotationNames.Comment);
RemoveAnnotation(ref annotations, RelationalAnnotationNames.Schema);
RemoveAnnotation(ref annotations, ScaffoldingAnnotationNames.DbSetName);
RemoveAnnotation(ref annotations, RelationalAnnotationNames.ViewDefinition);

if (!useDataAnnotations)
var isView = entityType.FindAnnotation(RelationalAnnotationNames.ViewDefinition) != null;
if (!useDataAnnotations || isView)
{
GenerateTableName(entityType);
}
Expand Down Expand Up @@ -526,7 +528,8 @@ private void GenerateTableName(IEntityType entityType)
var explicitSchema = schema != null && schema != defaultSchema;
var explicitTable = explicitSchema || tableName != null && tableName != entityType.GetDbSetName();

if (explicitTable)
var isView = entityType.FindAnnotation(RelationalAnnotationNames.ViewDefinition) != null;
if (explicitTable || isView)
{
var parameterString = _code.Literal(tableName);
if (explicitSchema)
Expand All @@ -536,7 +539,7 @@ private void GenerateTableName(IEntityType entityType)

var lines = new List<string>
{
$".{nameof(RelationalEntityTypeBuilderExtensions.ToTable)}({parameterString})"
$".{(isView ? nameof(RelationalEntityTypeBuilderExtensions.ToView) : nameof(RelationalEntityTypeBuilderExtensions.ToTable))}({parameterString})"
};

AppendMultiLineFluentApi(entityType, lines);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ private void GenerateTableAttribute(IEntityType entityType)
var defaultSchema = entityType.Model.GetDefaultSchema();

var schemaParameterNeeded = schema != null && schema != defaultSchema;
var tableAttributeNeeded = schemaParameterNeeded || tableName != null && tableName != entityType.GetDbSetName();
var isView = entityType.FindAnnotation(RelationalAnnotationNames.ViewDefinition) != null;
var tableAttributeNeeded = !isView && (schemaParameterNeeded || tableName != null && tableName != entityType.GetDbSetName());

if (tableAttributeNeeded)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,14 @@ protected virtual EntityTypeBuilder VisitTable([NotNull] ModelBuilder modelBuild
var dbSetName = GetDbSetName(table);
builder.Metadata.SetDbSetName(dbSetName);

builder.ToTable(table.Name, table.Schema);
if (table is DatabaseView)
{
builder.ToView(table.Name, table.Schema);
}
else
{
builder.ToTable(table.Name, table.Schema);
}

if (table.Comment != null)
{
Expand Down

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions src/EFCore.Relational/Extensions/RelationalEntityTypeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -277,5 +277,22 @@ public static void SetComment(
[NotNull] this IConventionEntityType entityType, [CanBeNull] string comment, bool fromDataAnnotation = false)
=> entityType.SetOrRemoveAnnotation(RelationalAnnotationNames.Comment, comment, fromDataAnnotation);

/// <summary>
/// Gets a value indicating whether the entity type is ignored by Migrations.
/// </summary>
/// <param name="entityType">The entity type.</param>
/// <returns>A value indicating whether the entity type is ignored by Migrations.</returns>
public static bool MigrationsIgnored([NotNull] this IEntityType entityType)
{
if (entityType.BaseType != null)
{
return entityType.BaseType.MigrationsIgnored();
}

var viewDefinition = entityType.FindAnnotation(RelationalAnnotationNames.ViewDefinition);

return (viewDefinition != null && viewDefinition.Value == null)
|| entityType.GetDefiningQuery() != null;
}
}
}
18 changes: 9 additions & 9 deletions src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ protected virtual void ValidateDbFunctions([NotNull] IModel model, [NotNull] IDi

foreach (var parameter in dbFunction.Parameters)
{
if(parameter.TypeMapping == null)
if (parameter.TypeMapping == null)
{
throw new InvalidOperationException(
RelationalStrings.DbFunctionInvalidParameterType(
Expand Down Expand Up @@ -152,7 +152,7 @@ protected virtual void ValidateSharedTableCompatibility(
[NotNull] IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)
{
var tables = new Dictionary<string, List<IEntityType>>();
foreach (var entityType in model.GetEntityTypes().Where(et => et.FindPrimaryKey() != null))
foreach (var entityType in model.GetEntityTypes())
{
var tableName = Format(entityType.GetSchema(), entityType.GetTableName());

Expand Down Expand Up @@ -196,11 +196,11 @@ protected virtual void ValidateSharedTableCompatibility(
foreach (var mappedType in mappedTypes)
{
if (mappedType.BaseType != null
|| mappedType.FindForeignKeys(mappedType.FindPrimaryKey().Properties)
|| (mappedType.FindPrimaryKey() != null && mappedType.FindForeignKeys(mappedType.FindPrimaryKey().Properties)
.Any(
fk => fk.PrincipalKey.IsPrimaryKey()
&& fk.PrincipalEntityType.RootType() != mappedType
&& unvalidatedTypes.Contains(fk.PrincipalEntityType)))
&& unvalidatedTypes.Contains(fk.PrincipalEntityType))))
{
continue;
}
Expand Down Expand Up @@ -235,17 +235,17 @@ protected virtual void ValidateSharedTableCompatibility(
{
var key = entityType.FindPrimaryKey();
var otherKey = nextEntityType.FindPrimaryKey();
if (key.GetName() != otherKey.GetName())
if (key?.GetName() != otherKey?.GetName())
{
throw new InvalidOperationException(
RelationalStrings.IncompatibleTableKeyNameMismatch(
tableName,
entityType.DisplayName(),
nextEntityType.DisplayName(),
key.GetName(),
key.Properties.Format(),
otherKey.GetName(),
otherKey.Properties.Format()));
key?.GetName(),
key?.Properties.Format(),
otherKey?.GetName(),
otherKey?.Properties.Format()));
}

var nextComment = nextEntityType.GetComment();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,6 @@ private static void TryUniquifyTableNames(
{
foreach (var entityType in model.GetEntityTypes())
{
if (entityType.FindPrimaryKey() == null)
{
continue;
}

var tableName = (Schema: entityType.GetSchema(), TableName: entityType.GetTableName());
if (!tables.TryGetValue(tableName, out var entityTypes))
{
Expand Down Expand Up @@ -131,8 +126,8 @@ private static void TryUniquifyTableNames(
private static bool ShouldUniquify(IConventionEntityType entityType, ICollection<IConventionEntityType> entityTypes)
{
var rootType = entityType.RootType();
var pkProperty = entityType.FindPrimaryKey().Properties[0];
var rootSharedTableType = pkProperty.FindSharedTableRootPrimaryKeyProperty()?.DeclaringEntityType;
var pkProperty = entityType.FindPrimaryKey()?.Properties[0];
var rootSharedTableType = pkProperty?.FindSharedTableRootPrimaryKeyProperty()?.DeclaringEntityType;

foreach (var otherEntityType in entityTypes)
{
Expand All @@ -142,8 +137,8 @@ private static bool ShouldUniquify(IConventionEntityType entityType, ICollection
return false;
}

var otherPkProperty = otherEntityType.FindPrimaryKey().Properties[0];
var otherRootSharedTableType = otherPkProperty.FindSharedTableRootPrimaryKeyProperty()?.DeclaringEntityType;
var otherPkProperty = otherEntityType.FindPrimaryKey()?.Properties[0];
var otherRootSharedTableType = otherPkProperty?.FindSharedTableRootPrimaryKeyProperty()?.DeclaringEntityType;
if (otherRootSharedTableType == entityType
|| (otherRootSharedTableType == rootSharedTableType
&& otherRootSharedTableType != null))
Expand Down
6 changes: 3 additions & 3 deletions src/EFCore.Relational/Metadata/Internal/TableMapping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,12 @@ public TableMapping(
public virtual IEntityType GetRootType()
=> EntityTypes.SingleOrDefault(
t => t.BaseType == null
&& t.FindForeignKeys(t.FindDeclaredPrimaryKey().Properties)
&& (t.FindDeclaredPrimaryKey() == null || t.FindForeignKeys(t.FindDeclaredPrimaryKey().Properties)
.All(
fk => !fk.PrincipalKey.IsPrimaryKey()
|| fk.PrincipalEntityType.RootType() == t
|| t.GetTableName() != fk.PrincipalEntityType.GetTableName()
|| t.GetSchema() != fk.PrincipalEntityType.GetSchema()));
|| t.GetSchema() != fk.PrincipalEntityType.GetSchema())));

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
Expand Down Expand Up @@ -155,7 +155,7 @@ public virtual IEnumerable<ICheckConstraint> GetCheckConstraints()
public static IReadOnlyList<TableMapping> GetTableMappings([NotNull] IModel model)
{
var tables = new Dictionary<(string Schema, string TableName), List<IEntityType>>();
foreach (var entityType in model.GetEntityTypes().Where(et => et.FindPrimaryKey() != null))
foreach (var entityType in model.GetEntityTypes().Where(et => !et.MigrationsIgnored()))
{
var fullName = (entityType.GetSchema(), entityType.GetTableName());
if (!tables.TryGetValue(fullName, out var mappedEntityTypes))
Expand Down
5 changes: 5 additions & 0 deletions src/EFCore.Relational/Metadata/RelationalAnnotationNames.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,5 +93,10 @@ public static class RelationalAnnotationNames
/// A flag indicating whether the property is constrained to fixed length values.
/// </summary>
public const string IsFixedLength = Prefix + "IsFixedLength";

/// <summary>
/// The definition of a database view.
/// </summary>
public const string ViewDefinition = Prefix + "ViewDefinition";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -617,7 +617,10 @@ protected virtual IEnumerable<MigrationOperation> Add(
createTableOperation.Columns.AddRange(
GetSortedProperties(target).SelectMany(p => Add(p, diffContext, inline: true)).Cast<AddColumnOperation>());
var primaryKey = target.EntityTypes[0].FindPrimaryKey();
createTableOperation.PrimaryKey = Add(primaryKey, diffContext).Cast<AddPrimaryKeyOperation>().Single();
if (primaryKey != null)
{
createTableOperation.PrimaryKey = Add(primaryKey, diffContext).Cast<AddPrimaryKeyOperation>().Single();
}
createTableOperation.UniqueConstraints.AddRange(
target.GetKeys().Where(k => !k.IsPrimaryKey()).SelectMany(k => Add(k, diffContext))
.Cast<AddUniqueConstraintOperation>());
Expand Down Expand Up @@ -2147,7 +2150,7 @@ protected virtual bool HasDifferences([NotNull] IEnumerable<IAnnotation> source,
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
protected virtual IEnumerable<string> GetSchemas([NotNull] IModel model)
=> model.GetRootEntityTypes().Select(t => t.GetSchema())
=> model.GetRootEntityTypes().Where(t => !t.MigrationsIgnored()).Select(t => t.GetSchema())
.Concat(model.GetSequences().Select(s => s.Schema))
.Where(s => !string.IsNullOrEmpty(s))
.Distinct();
Expand Down
3 changes: 1 addition & 2 deletions src/EFCore.Relational/Migrations/MigrationsSqlGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Update;
Expand Down Expand Up @@ -1580,7 +1579,7 @@ protected virtual IEnumerable<IEntityType> FindEntityTypes(
[CanBeNull] string schema,
[NotNull] string tableName)
=> model?.GetEntityTypes().Where(
t => t.GetTableName() == tableName && t.GetSchema() == schema && t.FindPrimaryKey() != null);
t => t.GetTableName() == tableName && t.GetSchema() == schema && !t.MigrationsIgnored());

/// <summary>
/// <para>
Expand Down
12 changes: 12 additions & 0 deletions src/EFCore.Relational/Scaffolding/Metadata/DatabaseView.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

namespace Microsoft.EntityFrameworkCore.Scaffolding.Metadata
{
/// <summary>
/// A simple model for a database view used when reverse engineering an existing database.
/// </summary>
public class DatabaseView : DatabaseTable
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ public static SharedTableEntryMapFactory<TValue> CreateSharedTableEntryMapFactor
{
var principals = new Dictionary<IEntityType, IReadOnlyList<IEntityType>>(entityTypes.Count);
var dependents = new Dictionary<IEntityType, IReadOnlyList<IEntityType>>(entityTypes.Count);
foreach (var entityType in entityTypes)
foreach (var entityType in entityTypes.Where(t => t.FindPrimaryKey() != null))
{
var principalList = new List<IEntityType>();
foreach (var foreignKey in entityType.FindForeignKeys(entityType.FindPrimaryKey().Properties))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,8 @@ private IEnumerable<DatabaseTable> GetTables(
SELECT
SCHEMA_NAME([t].[schema_id]) AS [schema],
[t].[name],
CAST([e].[value] AS nvarchar(MAX)) AS [comment]";
CAST([e].[value] AS nvarchar(MAX)) AS [comment],
'table' AS [type]";

if (supportsMemoryOptimizedTable)
{
Expand Down Expand Up @@ -487,7 +488,8 @@ FROM [sys].[extended_properties] AS [ep]
SELECT
SCHEMA_NAME([v].[schema_id]) AS [schema],
[v].[name],
CAST([e].[value] AS nvarchar(MAX)) AS [comment]";
CAST([e].[value] AS nvarchar(MAX)) AS [comment],
'view' AS [type]";

if (supportsMemoryOptimizedTable)
{
Expand Down Expand Up @@ -520,15 +522,17 @@ FROM [sys].[views] AS [v]
var schema = reader.GetValueOrDefault<string>("schema");
var name = reader.GetValueOrDefault<string>("name");
var comment = reader.GetValueOrDefault<string>("comment");
var type = reader.GetValueOrDefault<string>("type");

_logger.TableFound(DisplayName(schema, name));

var table = new DatabaseTable
{
Schema = schema,
Name = name,
Comment = comment,
};
var table = type == "table"
? new DatabaseTable()
: new DatabaseView();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @ErikEJ

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 😎


table.Schema = schema;
table.Name = name;
table.Comment = comment;

if (supportsMemoryOptimizedTable)
{
Expand Down Expand Up @@ -832,7 +836,7 @@ FROM [sys].[indexes] i
)";
}

commandText += @"
commandText += @"
ORDER BY [table_schema], [table_name], [index_name], [ic].[key_ordinal]";

command.CommandText = commandText;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ private IEnumerable<DatabaseTable> GetTables(DbConnection connection, IEnumerabl
using (var command = connection.CreateCommand())
{
command.CommandText = new StringBuilder()
.AppendLine("SELECT \"name\"")
.AppendLine("SELECT \"name\", \"type\"")
.AppendLine("FROM \"sqlite_master\"")
.Append("WHERE \"type\" IN ('table', 'view') AND instr(\"name\", 'sqlite_') <> 1 AND \"name\" NOT IN ('")
.Append(HistoryRepository.DefaultTableName)
Expand All @@ -179,10 +179,12 @@ private IEnumerable<DatabaseTable> GetTables(DbConnection connection, IEnumerabl

_logger.TableFound(name);

var table = new DatabaseTable
{
Name = name
};
var type = reader.GetString(1);
var table = type == "table"
? new DatabaseTable()
: new DatabaseView();

table.Name = name;

foreach (var column in GetColumns(connection, name))
{
Expand Down
Loading