diff --git a/src/EFCore.Jet/Scaffolding/Internal/JetCodeGenerator.cs b/src/EFCore.Jet/Scaffolding/Internal/JetCodeGenerator.cs
index 3f9431b..9f1c011 100644
--- a/src/EFCore.Jet/Scaffolding/Internal/JetCodeGenerator.cs
+++ b/src/EFCore.Jet/Scaffolding/Internal/JetCodeGenerator.cs
@@ -1,11 +1,19 @@
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+// 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.
using JetBrains.Annotations;
+using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.EntityFrameworkCore.Scaffolding;
namespace EntityFrameworkCore.Jet.Scaffolding.Internal
{
+ ///
+ /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+ /// the same compatibility standards as public APIs. It may be changed or removed without notice in
+ /// any release. You should only use it directly in your code with extreme caution and knowing that
+ /// doing so can result in application failures when updating to a new Entity Framework Core release.
+ ///
public class JetCodeGenerator : ProviderCodeGenerator
{
///
@@ -18,17 +26,18 @@ namespace EntityFrameworkCore.Jet.Scaffolding.Internal
}
///
- /// This API supports the Entity Framework Core infrastructure and is not intended to be used
- /// directly from your code. This API may change or be removed in future releases.
+ /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+ /// the same compatibility standards as public APIs. It may be changed or removed without notice in
+ /// any release. You should only use it directly in your code with extreme caution and knowing that
+ /// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public override MethodCallCodeFragment GenerateUseProvider(
string connectionString,
MethodCallCodeFragment providerOptions)
=> new MethodCallCodeFragment(
- nameof(JetDbContextOptionsExtensions.UseJet),
+ nameof(JetDbContextOptionsBuilderExtensions.UseJet),
providerOptions == null
? new object[] { connectionString }
: new object[] { connectionString, new NestedClosureCodeFragment("x", providerOptions) });
-
}
}
diff --git a/src/EFCore.Jet/Scaffolding/Internal/JetDatabaseModelFactory.cs b/src/EFCore.Jet/Scaffolding/Internal/JetDatabaseModelFactory.cs
index ec6a345..332f937 100644
--- a/src/EFCore.Jet/Scaffolding/Internal/JetDatabaseModelFactory.cs
+++ b/src/EFCore.Jet/Scaffolding/Internal/JetDatabaseModelFactory.cs
@@ -8,7 +8,6 @@ using System.Data.Jet;
using System.Diagnostics;
using System.Linq;
using EntityFrameworkCore.Jet.Internal;
-using EntityFrameworkCore.Jet.Metadata.Internal;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
@@ -16,7 +15,6 @@ using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Scaffolding;
using Microsoft.EntityFrameworkCore.Scaffolding.Metadata;
-using Microsoft.EntityFrameworkCore.Scaffolding.Metadata.Internal;
using EntityFrameworkCore.Jet.Utilities;
namespace EntityFrameworkCore.Jet.Scaffolding.Internal
@@ -25,43 +23,30 @@ namespace EntityFrameworkCore.Jet.Scaffolding.Internal
/// This API supports the Entity Framework Core infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
///
- public class JetDatabaseModelFactory : IDatabaseModelFactory
+ public class JetDatabaseModelFactory : DatabaseModelFactory
{
private DbConnection _connection;
private Version _serverVersion;
private HashSet _tablesToInclude;
- private HashSet _schemasToInclude;
- private HashSet _selectedSchemas;
private HashSet _selectedTables;
private DatabaseModel _databaseModel;
private Dictionary _tables;
private Dictionary _tableColumns;
- ///
- /// This API supports the Entity Framework Core infrastructure and is not intended to be used
- /// directly from your code. This API may change or be removed in future releases.
- ///
- private static string SchemaQualifiedKey([NotNull] string name, [CanBeNull] string schema = null) => "[" + (schema ?? "") + "].[" + name + "]";
-
- private static string TableKey(DatabaseTable table) => SchemaQualifiedKey(table.Name, table.Schema);
- private static string ColumnKey(DatabaseTable table, string columnName) => TableKey(table) + ".[" + columnName + "]";
-
- private static readonly ISet _dateTimePrecisionTypes = new HashSet { "datetimeoffset", "datetime2", "time" };
-
- // see https://msdn.microsoft.com/en-us/library/ff878091.aspx
-
- private static readonly List _schemaPatterns = new List
- {
- "{schema}",
- "[{schema}]"
- };
+ private static string ObjectKey([NotNull] string name)
+ => "[" + name + "]";
+
+ private static string TableKey(DatabaseTable table)
+ => TableKey(table.Name);
+
+ private static string TableKey(String tableName)
+ => ObjectKey(tableName);
+
+ private static string ColumnKey(DatabaseTable table, string columnName)
+ => TableKey(table) + "." + ObjectKey(columnName);
private static readonly List _tablePatterns = new List
{
- "{schema}.{table}",
- "[{schema}].[{table}]",
- "{schema}.[{table}]",
- "[{schema}].{table}",
"{table}",
"[{table}]"
};
@@ -88,39 +73,37 @@ namespace EntityFrameworkCore.Jet.Scaffolding.Internal
_connection = null;
_serverVersion = null;
_selectedTables = new HashSet(StringComparer.OrdinalIgnoreCase);
- _selectedSchemas = new HashSet(StringComparer.OrdinalIgnoreCase);
_tablesToInclude = new HashSet(StringComparer.OrdinalIgnoreCase);
- _schemasToInclude = new HashSet(StringComparer.OrdinalIgnoreCase);
_databaseModel = new DatabaseModel();
_tables = new Dictionary();
_tableColumns = new Dictionary(StringComparer.OrdinalIgnoreCase);
}
///
- /// This API supports the Entity Framework Core infrastructure and is not intended to be used
- /// directly from your code. This API may change or be removed in future releases.
+ /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+ /// the same compatibility standards as public APIs. It may be changed or removed without notice in
+ /// any release. You should only use it directly in your code with extreme caution and knowing that
+ /// doing so can result in application failures when updating to a new Entity Framework Core release.
///
- public virtual DatabaseModel Create(string connectionString, IEnumerable tables, IEnumerable schemas)
+ public override DatabaseModel Create(string connectionString, DatabaseModelFactoryOptions options)
{
Check.NotEmpty(connectionString, nameof(connectionString));
- Check.NotNull(tables, nameof(tables));
- Check.NotNull(schemas, nameof(schemas));
+ Check.NotNull(options, nameof(options));
- using (var connection = new JetConnection(connectionString))
- {
- return Create(connection, tables, schemas);
- }
+ using var connection = new JetConnection(connectionString);
+ return Create(connection, options);
}
///
- /// This API supports the Entity Framework Core infrastructure and is not intended to be used
- /// directly from your code. This API may change or be removed in future releases.
+ /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+ /// the same compatibility standards as public APIs. It may be changed or removed without notice in
+ /// any release. You should only use it directly in your code with extreme caution and knowing that
+ /// doing so can result in application failures when updating to a new Entity Framework Core release.
///
- public virtual DatabaseModel Create(DbConnection connection, IEnumerable tables, IEnumerable schemas)
+ public override DatabaseModel Create(DbConnection connection, DatabaseModelFactoryOptions options)
{
Check.NotNull(connection, nameof(connection));
- Check.NotNull(tables, nameof(tables));
- Check.NotNull(schemas, nameof(schemas));
+ Check.NotNull(options, nameof(options));
ResetState();
@@ -131,23 +114,20 @@ namespace EntityFrameworkCore.Jet.Scaffolding.Internal
{
_connection.Open();
}
+
try
{
- foreach (var schema in schemas)
- {
- _schemasToInclude.Add(schema);
- }
-
- foreach (var table in tables)
+ foreach (var table in options.Tables)
{
_tablesToInclude.Add(table);
}
+ _databaseModel.DefaultSchema = null;
_databaseModel.DatabaseName = _connection.Database;
+ // CHECK: Is this actually set?
Version.TryParse(_connection.ServerVersion, out _serverVersion);
- GetDefaultSchema();
GetTables();
GetColumns();
GetPrimaryKeys();
@@ -170,30 +150,17 @@ namespace EntityFrameworkCore.Jet.Scaffolding.Internal
private void CheckSelectionsMatched()
{
- foreach (var schema in _schemasToInclude.Except(_selectedSchemas, StringComparer.OrdinalIgnoreCase))
- {
- Logger.MissingSchemaWarning(schema);
- }
-
foreach (var table in _tablesToInclude.Except(_selectedTables, StringComparer.OrdinalIgnoreCase))
{
Logger.MissingTableWarning(table);
}
}
-
- private void GetDefaultSchema()
- {
- _databaseModel.DefaultSchema = "Jet";
- }
-
-
-
private void GetTables()
{
var command = _connection.CreateCommand();
- command.CommandText =
- $"SHOW TABLES WHERE Name <> '{HistoryRepository.DefaultTableName}'";
+ command.CommandText = $"SHOW TABLES WHERE Name <> '{HistoryRepository.DefaultTableName}'";
+
using (var reader = command.ExecuteReader())
{
while (reader.Read())
@@ -201,13 +168,13 @@ namespace EntityFrameworkCore.Jet.Scaffolding.Internal
var table = new DatabaseTable
{
Database = _databaseModel,
- Schema = "Jet",
+ Schema = null,
Name = reader.GetValueOrDefault("Name")
};
- if (AllowsTable(table.Schema, table.Name))
+ if (AllowsTable(table.Name))
{
- Logger.TableFound(DisplayName(table.Schema, table.Name));
+ Logger.TableFound(table.Name);
_databaseModel.Tables.Add(table);
_tables[TableKey(table)] = table;
}
@@ -215,27 +182,16 @@ namespace EntityFrameworkCore.Jet.Scaffolding.Internal
}
}
- private bool AllowsTable(string schema, string table)
+ private bool AllowsTable(string table)
{
- if (_schemasToInclude.Count == 0
- && _tablesToInclude.Count == 0)
+ if (_tablesToInclude.Count == 0)
{
return true;
}
- foreach (var schemaPattern in _schemaPatterns)
- {
- var key = schemaPattern.Replace("{schema}", schema);
- if (_schemasToInclude.Contains(key))
- {
- _selectedSchemas.Add(schema);
- return true;
- }
- }
-
foreach (var tablePattern in _tablePatterns)
{
- var key = tablePattern.Replace("{schema}", schema).Replace("{table}", table);
+ var key = tablePattern.Replace("{table}", table);
if (_tablesToInclude.Contains(key))
{
_selectedTables.Add(key);
@@ -260,41 +216,40 @@ ORDER BY
{
while (reader.Read())
{
- var schemaName = "Jet";
var tableName = reader.GetValueOrDefault("Table");
var columnName = reader.GetValueOrDefault("Name");
var dataTypeName = reader.GetValueOrDefault("TypeName");
- var dataTypeSchemaName = "Jet";
var ordinal = reader.GetValueOrDefault("Ordinal");
var nullable = reader.GetValueOrDefault("IsNullable");
// ReSharper disable once UnusedVariable
- var primaryKeyOrdinal = reader.GetValueOrDefault("IsKey") ? (int?)reader.GetValueOrDefault("Ordinal") : null;
+ var primaryKeyOrdinal = reader.GetValueOrDefault("IsKey")
+ ? (int?) reader.GetValueOrDefault("Ordinal")
+ : null;
var defaultValue = reader.GetValueOrDefault("Default");
- var computedValue = (string)null;
var precision = reader.GetValueOrDefault("Precision");
var scale = reader.GetValueOrDefault("Scale");
var maxLength = reader.GetValueOrDefault("MaxLength");
var isIdentity = reader.GetValueOrDefault("IsIdentity");
Logger.ColumnFound(
- DisplayName(schemaName, tableName),
+ tableName,
columnName,
ordinal,
- DisplayName(dataTypeSchemaName, dataTypeName),
- maxLength,
- precision,
- scale,
+ dataTypeName,
+ maxLength ?? -1,
+ precision ?? 0,
+ scale ?? 0,
nullable,
isIdentity,
defaultValue,
- computedValue);
+ null);
- if (!_tables.TryGetValue(SchemaQualifiedKey(tableName, schemaName), out var table))
+ if (!_tables.TryGetValue(TableKey(tableName), out var table))
continue;
- string storeType;
- storeType = GetStoreType(dataTypeName, precision, scale, maxLength);
+ var storeType = GetStoreType(dataTypeName, precision, scale, maxLength);
+ // CHECK: Jet behavior.
if (defaultValue == "(NULL)")
{
defaultValue = null;
@@ -307,17 +262,18 @@ ORDER BY
StoreType = storeType,
IsNullable = nullable,
DefaultValueSql = defaultValue,
- ComputedColumnSql = computedValue,
+ ComputedColumnSql = null,
ValueGenerated = isIdentity
? ValueGenerated.OnAdd
- : (storeType) == "rowversion"
+ : storeType == "timestamp"
? ValueGenerated.OnAddOrUpdate
: default(ValueGenerated?)
};
- if (storeType == "rowversion")
+ if (storeType == "timestamp")
{
- column[ScaffoldingAnnotationNames.ConcurrencyToken] = true;
+ // Note: annotation name must match `ScaffoldingAnnotationNames.ConcurrencyToken`
+ column["ConcurrencyToken"] = true;
}
table.Columns.Add(column);
@@ -328,36 +284,28 @@ ORDER BY
private string GetStoreType(string dataTypeName, int? precision, int? scale, int? maxLength)
{
- if (dataTypeName == "decimal"
- || dataTypeName == "numeric")
+ if (string.Equals(dataTypeName, "decimal", StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(dataTypeName, "numeric", StringComparison.OrdinalIgnoreCase))
{
return $"{dataTypeName}({precision}, {scale.GetValueOrDefault(0)})";
}
- if (_dateTimePrecisionTypes.Contains(dataTypeName)
- && scale != null)
- {
- return $"{dataTypeName}({scale})";
- }
- if (maxLength == -1)
+
+ if (maxLength.HasValue)
{
- if (string.Equals(dataTypeName, "varchar", StringComparison.InvariantCultureIgnoreCase))
- return "text";
- else if (string.Equals(dataTypeName, "varbinary", StringComparison.InvariantCultureIgnoreCase))
- return "image";
- else
- throw new InvalidOperationException("Unexpected type " + dataTypeName);
- }
+ if (maxLength == -1)
+ {
+ if (string.Equals(dataTypeName, "varchar", StringComparison.OrdinalIgnoreCase))
+ return "longchar";
- if (dataTypeName == "timestamp")
- return "rowversion";
+ if (string.Equals(dataTypeName, "varbinary", StringComparison.OrdinalIgnoreCase))
+ return "longbinary";
- if (dataTypeName == "bit")
- {
- return "bit";
- }
+ throw new InvalidOperationException("Unexpected type " + dataTypeName);
+ }
- if (maxLength.HasValue && maxLength > 0)
- return $"{dataTypeName}({maxLength.Value})";
+ if (maxLength > 0)
+ return $"{dataTypeName}({maxLength.Value})";
+ }
return dataTypeName;
}
@@ -378,10 +326,8 @@ ORDER BY
DatabasePrimaryKey primaryKey = null;
while (reader.Read())
{
- var schemaName = "Jet";
var tableName = reader.GetValueOrDefault("TableName");
var indexName = reader.GetValueOrDefault("ConstraintName");
- var typeDesc = reader.GetValueOrDefault("ConstraintType");
var columnName = reader.GetValueOrDefault("ColumnName");
// ReSharper disable once UnusedVariable
var indexOrdinal = reader.GetValueOrDefault("ColumnOrdinal");
@@ -390,16 +336,14 @@ ORDER BY
if (primaryKey == null
|| primaryKey.Name != indexName
// ReSharper disable once PossibleNullReferenceException
- || primaryKey.Table.Name != tableName
- || primaryKey.Table.Schema != schemaName)
+ || primaryKey.Table.Name != tableName)
{
- if (!_tables.TryGetValue(SchemaQualifiedKey(tableName, schemaName), out var table))
+ if (!_tables.TryGetValue(TableKey(tableName), out var table))
{
continue;
}
- Logger.PrimaryKeyFound(
- indexName, DisplayName(schemaName, tableName));
+ Logger.PrimaryKeyFound(indexName, tableName);
primaryKey = new DatabasePrimaryKey
{
@@ -407,11 +351,6 @@ ORDER BY
Name = indexName
};
- if (typeDesc == "NONCLUSTERED")
- {
- primaryKey[JetAnnotationNames.Clustered] = false;
- }
-
Debug.Assert(table.PrimaryKey == null);
table.PrimaryKey = primaryKey;
}
@@ -440,10 +379,9 @@ ORDER BY
DatabaseUniqueConstraint uniqueConstraint = null;
while (reader.Read())
{
- var schemaName = "Jet";
+ var schemaName = "Jet"; // TODO: Change to `null`.
var tableName = reader.GetValueOrDefault("TableName");
var indexName = reader.GetValueOrDefault("ConstraintName");
- var typeDesc = reader.GetValueOrDefault("ConstraintType");
var columnName = reader.GetValueOrDefault("ColumnName");
// ReSharper disable once UnusedVariable
var indexOrdinal = reader.GetValueOrDefault("ColumnOrdinal");
@@ -455,12 +393,12 @@ ORDER BY
|| uniqueConstraint.Table.Name != tableName
|| uniqueConstraint.Table.Schema != schemaName)
{
- if (!_tables.TryGetValue(SchemaQualifiedKey(tableName, schemaName), out var table))
+ if (!_tables.TryGetValue(TableKey(tableName), out var table))
{
continue;
}
- Logger.UniqueConstraintFound(indexName, DisplayName(schemaName, tableName));
+ Logger.UniqueConstraintFound(indexName, tableName);
uniqueConstraint = new DatabaseUniqueConstraint
{
@@ -468,11 +406,6 @@ ORDER BY
Name = indexName
};
- if (typeDesc == "CLUSTERED")
- {
- uniqueConstraint[JetAnnotationNames.Clustered] = true;
- }
-
table.UniqueConstraints.Add(uniqueConstraint);
}
@@ -502,11 +435,10 @@ ORDER BY
DatabaseIndex index = null;
while (reader.Read())
{
- var schemaName = "Jet";
+ var schemaName = "Jet"; // TODO: Change to `null`.
var tableName = reader.GetValueOrDefault("Table");
var indexName = reader.GetValueOrDefault("Index");
var isUnique = reader.GetValueOrDefault("IsUnique");
- var typeDesc = "NON CLUSTERED";
var columnName = reader.GetValueOrDefault("Name");
// ReSharper disable once UnusedVariable
var indexOrdinal = reader.GetValueOrDefault("Ordinal");
@@ -518,12 +450,12 @@ ORDER BY
|| index.Table.Name != tableName
|| index.Table.Schema != schemaName)
{
- if (!_tables.TryGetValue(SchemaQualifiedKey(tableName, schemaName), out var table))
+ if (!_tables.TryGetValue(TableKey(tableName), out var table))
{
continue;
}
- Logger.IndexFound(indexName, DisplayName(schemaName, tableName), isUnique);
+ Logger.IndexFound(indexName, tableName, isUnique);
index = new DatabaseIndex
{
@@ -533,11 +465,6 @@ ORDER BY
Filter = null
};
- if (typeDesc == "CLUSTERED")
- {
- index[JetAnnotationNames.Clustered] = true;
- }
-
table.Indexes.Add(index);
}
@@ -568,10 +495,10 @@ ORDER BY
DatabaseForeignKey foreignKey = null;
while (reader.Read())
{
- var schemaName = "Jet";
+ var schemaName = "Jet"; // TODO: Change to `null`.
var tableName = reader.GetValueOrDefault("FromTable");
var constraintName = reader.GetValueOrDefault("ConstraintId");
- var principalTableSchemaName = "Jet";
+ var principalTableSchemaName = "Jet"; // TODO: Change to `null`.
var principalTableName = reader.GetValueOrDefault("ToTable");
var fromColumnName = reader.GetValueOrDefault("FromColumn");
var toColumnName = reader.GetValueOrDefault("ToColumn");
@@ -583,8 +510,8 @@ ORDER BY
Logger.ForeignKeyFound(
constraintName,
- DisplayName(schemaName, tableName),
- DisplayName(schemaName, principalTableName),
+ tableName,
+ principalTableName,
deleteAction);
if (foreignKey == null
@@ -596,7 +523,7 @@ ORDER BY
lastFkSchemaName = schemaName;
lastFkTableName = tableName;
- if (!_tables.TryGetValue(SchemaQualifiedKey(tableName, schemaName), out var table))
+ if (!_tables.TryGetValue(TableKey(tableName), out var table))
{
continue;
}
@@ -605,13 +532,13 @@ ORDER BY
if (!string.IsNullOrEmpty(principalTableSchemaName)
&& !string.IsNullOrEmpty(principalTableName))
{
- _tables.TryGetValue(SchemaQualifiedKey(principalTableName, principalTableSchemaName), out principalTable);
+ _tables.TryGetValue(TableKey(principalTableName), out principalTable);
}
if (principalTable == null)
{
Logger.ForeignKeyReferencesMissingPrincipalTableWarning(
- constraintName, DisplayName(schemaName, tableName), DisplayName(principalTableSchemaName, principalTableName));
+ constraintName, tableName, principalTableName);
}
foreignKey = new DatabaseForeignKey
@@ -643,9 +570,6 @@ ORDER BY
}
}
- private static string DisplayName(string schema, string name)
- => (!string.IsNullOrEmpty(schema) ? schema + "." : "") + name;
-
private static ReferentialAction? ConvertToReferentialAction(string onDeleteAction)
{
switch (onDeleteAction.ToUpperInvariant())
@@ -670,4 +594,4 @@ ORDER BY
}
}
}
-}
+}
\ No newline at end of file