Skip to content

Commit

Permalink
Change the default subfolder/subnamespace for compiled models to Comp…
Browse files Browse the repository at this point in the history
…iledModels

Handle context types in the global namespace

Fixes #25058
Fixes #25059
  • Loading branch information
AndriySvyryd committed Aug 19, 2021
1 parent f8ef489 commit 5d91778
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 25 deletions.
25 changes: 18 additions & 7 deletions src/EFCore.Design/Design/Internal/DbContextOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,16 +138,27 @@ public virtual string ScriptDbContext(string? contextType)
/// 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.
/// </summary>
public virtual void Optimize(string? outputDir, string? modelNamespace, string? contextType)
public virtual void Optimize(string? outputDir, string? modelNamespace, string? contextTypeName)
{
using var context = CreateContext(contextType);
using var context = CreateContext(contextTypeName);
var contextType = context.GetType();

var services = _servicesBuilder.Build(context);
var scaffolder = services.GetRequiredService<ICompiledModelScaffolder>();

outputDir = outputDir != null
? Path.GetFullPath(Path.Combine(_projectDir, outputDir))
: _projectDir;
if (outputDir == null)
{
var contextSubNamespace = contextType.Namespace ?? "";
if (!string.IsNullOrEmpty(_rootNamespace)
&& contextSubNamespace.StartsWith(_rootNamespace, StringComparison.Ordinal))
{
contextSubNamespace = contextSubNamespace[_rootNamespace.Length..];
}

outputDir = Path.Combine(contextSubNamespace.Replace('.', Path.DirectorySeparatorChar), "CompiledModels");
}

outputDir = Path.GetFullPath(Path.Combine(_projectDir, outputDir));

var finalModelNamespace = modelNamespace ?? GetNamespaceFromOutputPath(outputDir) ?? "";

Expand All @@ -156,13 +167,13 @@ public virtual void Optimize(string? outputDir, string? modelNamespace, string?
outputDir,
new CompiledModelCodeGenerationOptions
{
ContextType = context.GetType(),
ContextType = contextType,
ModelNamespace = finalModelNamespace,
Language = _language,
UseNullableReferenceTypes = _nullable
});

var fullName = context.GetType().ShortDisplayName() + "Model";
var fullName = contextType.ShortDisplayName() + "Model";
if (!string.IsNullOrEmpty(modelNamespace))
{
fullName = modelNamespace + "." + fullName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,12 +141,14 @@ private string CreateModel(
bool nullable)
{
var mainBuilder = new IndentedStringBuilder();
var namespaces = new SortedSet<string>(new NamespaceComparer()) {
contextType.Namespace!,
var namespaces = new SortedSet<string>(new NamespaceComparer())
{
typeof(RuntimeModel).Namespace!,
typeof(DbContextAttribute).Namespace!
};

AddNamespace(contextType, namespaces);

if (!string.IsNullOrEmpty(@namespace))
{
mainBuilder
Expand Down Expand Up @@ -1371,14 +1373,14 @@ parameters with

private static void AddNamespace(Type type, ISet<string> namespaces)
{
if (type.Namespace != null)
if (!string.IsNullOrEmpty(type.Namespace))
{
namespaces.Add(type.Namespace);
}

if (type.IsGenericType)
{
foreach(var argument in type.GenericTypeArguments)
foreach (var argument in type.GenericTypeArguments)
{
AddNamespace(argument, namespaces);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.ComponentModel;
using System.Linq.Expressions;
using System.Reflection;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.Cosmos.ValueGeneration.Internal;
using Microsoft.EntityFrameworkCore.Design;
Expand All @@ -28,6 +29,20 @@
using Newtonsoft.Json.Linq;
using Xunit;

public class GlobalNamespaceContext : Microsoft.EntityFrameworkCore.Scaffolding.Internal.CSharpRuntimeModelCodeGeneratorTest.ContextBase
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);

modelBuilder.Entity("1", e =>
{
e.Property<int>("Id");
e.HasKey("Id");
});
}
}

namespace Microsoft.EntityFrameworkCore.Scaffolding.Internal
{
public class CSharpRuntimeModelCodeGeneratorTest
Expand Down Expand Up @@ -122,20 +137,6 @@ public void Global_namespace_works()
});
}

public class GlobalNamespaceContext : ContextBase
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);

modelBuilder.Entity("1", e =>
{
e.Property<int>("Id");
e.HasKey("Id");
});
}
}

[ConditionalFact]
public void Throws_for_constructor_binding()
{
Expand Down

0 comments on commit 5d91778

Please sign in to comment.