From a8a62e1162b170c6bf3c2db31cafefbd1074cb6d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 26 Sep 2025 20:20:43 +0000 Subject: [PATCH 1/7] Initial plan From e1050077a32094aef2adafd5aa1dcb076d7a0db4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 26 Sep 2025 20:27:59 +0000 Subject: [PATCH 2/7] Update design-time services documentation and fix CustomTools.cs sample Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com> --- entity-framework/core/cli/services.md | 47 +++++++++++++++++-- .../Miscellaneous/CommandLine/CustomTools.cs | 24 ++++++++-- 2 files changed, 65 insertions(+), 6 deletions(-) diff --git a/entity-framework/core/cli/services.md b/entity-framework/core/cli/services.md index 985392c98b..d48a6f0b92 100644 --- a/entity-framework/core/cli/services.md +++ b/entity-framework/core/cli/services.md @@ -2,7 +2,7 @@ title: Design-time services - EF Core description: Information on Entity Framework Core design-time services author: SamMonoRT -ms.date: 10/22/2020 +ms.date: 01/17/2025 uid: core/cli/services --- # Design-time services @@ -11,6 +11,31 @@ Some services used by the tools are only used at design time. These services are [!code-csharp[Main](../../../samples/core/Miscellaneous/CommandLine/DesignTimeServices.cs#DesignTimeServices)] +### Advanced customizations + +You can override individual methods in design-time services. For example, to customize how type names are generated in scaffolded code, you can override the `ShouldUseFullName` method in `CSharpHelper`: + +```csharp +public class MyDesignTimeServices : IDesignTimeServices +{ + public void ConfigureDesignTimeServices(IServiceCollection services) + => services.AddSingleton(); +} + +public class MyCSharpHelper : CSharpHelper +{ + public MyCSharpHelper(ITypeMappingSource typeMappingSource) : base(typeMappingSource) + { + } + + public override bool ShouldUseFullName(Type type) + { + // Custom logic to determine when to use full type names + return base.ShouldUseFullName(type); + } +} +``` + ## Referencing Microsoft.EntityFrameworkCore.Design Microsoft.EntityFrameworkCore.Design is a DevelopmentDependency package. This means that the dependency won't flow transitively into other projects, and that you cannot, by default, reference its types. @@ -18,7 +43,7 @@ Microsoft.EntityFrameworkCore.Design is a DevelopmentDependency package. This me In order to reference its types and override design-time services, update the PackageReference item's metadata in your project file. ```xml - + all @@ -34,20 +59,36 @@ The following is a list of the design-time services. Service | Description ------------------------------------------------------------------------------------ | ----------- | Generates the code for corresponding model annotations. + | Generates candidate names for entities and properties. | Helps with generating C# code. + | Generates C# code for migration operations. + | Generates C# code for model snapshots. + | C# code generation utilities. | Pluralizes and singularizes words. | Generates code for a migration. + | Selects the appropriate migrations code generator. | The main class for managing migration files. + | Generates code for compiled model metadata. + | Selects the appropriate compiled model code generator. + | The main class for scaffolding compiled models. | Creates a database model from a database. | Generates code for a model. + | Selects the appropriate model code generator. | Generates OnConfiguring code. | The main class for scaffolding reverse engineered models. | Creates a model from a database model. + | Maps database types to .NET types during scaffolding. + | Processes model snapshots. + | Generates code for precompiled queries. + | Selects the appropriate precompiled query code generator. ## Using services -These services can also be useful for creating your own tools. For example, when you want to automate part of you design-time workflow. +These services can also be useful for creating your own tools. For example, when you want to automate part of your design-time workflow. You can build a service provider containing these services using the AddEntityFrameworkDesignTimeServices and AddDbContextDesignTimeServices extension methods. [!code-csharp[](../../../samples/core/Miscellaneous/CommandLine/CustomTools.cs#CustomTools)] + +> [!NOTE] +> In EF Core 6.0 and later, the design-time services registration has been streamlined. The `AddEntityFrameworkDesignTimeServices()` method automatically registers all necessary design-time services, and `AddDbContextDesignTimeServices(context)` adds the DbContext-specific services from the provided context instance. diff --git a/samples/core/Miscellaneous/CommandLine/CustomTools.cs b/samples/core/Miscellaneous/CommandLine/CustomTools.cs index d4e20448a1..c3c586fd50 100644 --- a/samples/core/Miscellaneous/CommandLine/CustomTools.cs +++ b/samples/core/Miscellaneous/CommandLine/CustomTools.cs @@ -1,6 +1,7 @@ using System.IO; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Design; +using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations.Design; using Microsoft.Extensions.DependencyInjection; @@ -12,19 +13,24 @@ public static void AddMigration(string migrationName) { var projectDir = Directory.GetCurrentDirectory(); var rootNamespace = "ConsoleApp1"; - var outputDir = "Migraitons"; + var outputDir = "Migrations"; #region CustomTools - var db = new MyDbContext(); + using var db = new MyDbContext(); // Create design-time services var serviceCollection = new ServiceCollection(); + + // Add the core design-time services serviceCollection.AddEntityFrameworkDesignTimeServices(); + + // Add services from the DbContext serviceCollection.AddDbContextDesignTimeServices(db); + var serviceProvider = serviceCollection.BuildServiceProvider(); // Add a migration - var migrationsScaffolder = serviceProvider.GetService(); + var migrationsScaffolder = serviceProvider.GetRequiredService(); var migration = migrationsScaffolder.ScaffoldMigration(migrationName, rootNamespace); migrationsScaffolder.Save(projectDir, migration, outputDir); #endregion @@ -33,4 +39,16 @@ public static void AddMigration(string migrationName) internal class MyDbContext : DbContext { + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder.UseSqlServer("Server=(localdb)\\MSSQLLocalDB;Database=MyDatabase;Trusted_Connection=true;"); + } + + public DbSet Blogs { get; set; } +} + +internal class Blog +{ + public int Id { get; set; } + public string Title { get; set; } } \ No newline at end of file From 2d8da4a4bcf4fb6cfc59bbb997db25a9b188eef5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 26 Sep 2025 20:31:01 +0000 Subject: [PATCH 3/7] Complete design-time services documentation updates - fix grammar and validate samples Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com> --- entity-framework/core/miscellaneous/internals/tools.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/entity-framework/core/miscellaneous/internals/tools.md b/entity-framework/core/miscellaneous/internals/tools.md index 92b213790d..56b7dc40b0 100644 --- a/entity-framework/core/miscellaneous/internals/tools.md +++ b/entity-framework/core/miscellaneous/internals/tools.md @@ -114,7 +114,7 @@ In a nutshell, here are some of the strategies it uses. ### Design-time services -In addition to the application services and the internal DbContext services, there is a third set of [design-time services](xref:core/cli/services). These aren't added to internal service provider since they're never needed at runtime. The design-time services are built by [DesignTimeServicesBuilder](https://github.com/dotnet/efcore/blob/main/src/EFCore.Design/Design/Internal/DesignTimeServicesBuilder.cs). There are two main path--one with a context instance and one without. The one without is primarily used when scaffolding a new DbContext. There are several extensibility points here to allow the user, providers, and extensions to override and customize the services. +In addition to the application services and the internal DbContext services, there is a third set of [design-time services](xref:core/cli/services). These aren't added to internal service provider since they're never needed at runtime. The design-time services are built by [DesignTimeServicesBuilder](https://github.com/dotnet/efcore/blob/main/src/EFCore.Design/Design/Internal/DesignTimeServicesBuilder.cs). There are two main paths--one with a context instance and one without. The one without is primarily used when scaffolding a new DbContext. There are several extensibility points here to allow the user, providers, and extensions to override and customize the services. The user can customize services by adding an implementation of `IDesignTimeServices` to the startup assembly. From b545bc7ba79e87b9cc32ba3bedb7e0fa297a8789 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 1 Oct 2025 00:32:06 +0000 Subject: [PATCH 4/7] Address review feedback - remove advanced customizations, update version, add provider services Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com> --- entity-framework/core/cli/services.md | 30 +------------------ .../Miscellaneous/CommandLine/CustomTools.cs | 13 +++++--- 2 files changed, 10 insertions(+), 33 deletions(-) diff --git a/entity-framework/core/cli/services.md b/entity-framework/core/cli/services.md index d48a6f0b92..73926d4e7b 100644 --- a/entity-framework/core/cli/services.md +++ b/entity-framework/core/cli/services.md @@ -11,31 +11,6 @@ Some services used by the tools are only used at design time. These services are [!code-csharp[Main](../../../samples/core/Miscellaneous/CommandLine/DesignTimeServices.cs#DesignTimeServices)] -### Advanced customizations - -You can override individual methods in design-time services. For example, to customize how type names are generated in scaffolded code, you can override the `ShouldUseFullName` method in `CSharpHelper`: - -```csharp -public class MyDesignTimeServices : IDesignTimeServices -{ - public void ConfigureDesignTimeServices(IServiceCollection services) - => services.AddSingleton(); -} - -public class MyCSharpHelper : CSharpHelper -{ - public MyCSharpHelper(ITypeMappingSource typeMappingSource) : base(typeMappingSource) - { - } - - public override bool ShouldUseFullName(Type type) - { - // Custom logic to determine when to use full type names - return base.ShouldUseFullName(type); - } -} -``` - ## Referencing Microsoft.EntityFrameworkCore.Design Microsoft.EntityFrameworkCore.Design is a DevelopmentDependency package. This means that the dependency won't flow transitively into other projects, and that you cannot, by default, reference its types. @@ -43,7 +18,7 @@ Microsoft.EntityFrameworkCore.Design is a DevelopmentDependency package. This me In order to reference its types and override design-time services, update the PackageReference item's metadata in your project file. ```xml - + all @@ -89,6 +64,3 @@ These services can also be useful for creating your own tools. For example, when You can build a service provider containing these services using the AddEntityFrameworkDesignTimeServices and AddDbContextDesignTimeServices extension methods. [!code-csharp[](../../../samples/core/Miscellaneous/CommandLine/CustomTools.cs#CustomTools)] - -> [!NOTE] -> In EF Core 6.0 and later, the design-time services registration has been streamlined. The `AddEntityFrameworkDesignTimeServices()` method automatically registers all necessary design-time services, and `AddDbContextDesignTimeServices(context)` adds the DbContext-specific services from the provided context instance. diff --git a/samples/core/Miscellaneous/CommandLine/CustomTools.cs b/samples/core/Miscellaneous/CommandLine/CustomTools.cs index c3c586fd50..13dc996b9c 100644 --- a/samples/core/Miscellaneous/CommandLine/CustomTools.cs +++ b/samples/core/Miscellaneous/CommandLine/CustomTools.cs @@ -1,8 +1,10 @@ using System.IO; +using System.Reflection; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Design; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations.Design; +using Microsoft.EntityFrameworkCore.Storage; using Microsoft.Extensions.DependencyInjection; namespace CommandLine; @@ -20,12 +22,15 @@ public static void AddMigration(string migrationName) // Create design-time services var serviceCollection = new ServiceCollection(); + serviceCollection.AddDbContextDesignTimeServices(db); - // Add the core design-time services + var provider = db.GetService().Name; + var providerAssembly = Assembly.Load(new AssemblyName(provider)); + var providerServicesAttribute = providerAssembly.GetCustomAttribute(); + var designTimeServicesType = providerAssembly.GetType(providerServicesAttribute.TypeName, throwOnError: true); + ((IDesignTimeServices)Activator.CreateInstance(designTimeServicesType)!).ConfigureDesignTimeServices(serviceCollection); + serviceCollection.AddEntityFrameworkDesignTimeServices(); - - // Add services from the DbContext - serviceCollection.AddDbContextDesignTimeServices(db); var serviceProvider = serviceCollection.BuildServiceProvider(); From ab5b232e0a321c081df6d287a6a91bb84cfd6270 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 1 Oct 2025 00:41:09 +0000 Subject: [PATCH 5/7] Add note about handling ambiguous type references in compiled models Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com> --- entity-framework/core/cli/services.md | 22 +++++++++++++++++++ .../advanced-performance-topics.md | 4 ++++ 2 files changed, 26 insertions(+) diff --git a/entity-framework/core/cli/services.md b/entity-framework/core/cli/services.md index 73926d4e7b..64ed70d92d 100644 --- a/entity-framework/core/cli/services.md +++ b/entity-framework/core/cli/services.md @@ -11,6 +11,28 @@ Some services used by the tools are only used at design time. These services are [!code-csharp[Main](../../../samples/core/Miscellaneous/CommandLine/DesignTimeServices.cs#DesignTimeServices)] +### Customizing individual services + +You can also override individual methods in design-time services. For example, to customize how type names are generated in scaffolded code to always use fully-qualified names (which can help avoid compilation errors due to ambiguous type references), you can override the `ShouldUseFullName` method in `CSharpHelper`: + +```csharp +public class MyDesignTimeServices : IDesignTimeServices +{ + public void ConfigureDesignTimeServices(IServiceCollection services) + => services.AddSingleton(); +} + +public class MyCSharpHelper : CSharpHelper +{ + public MyCSharpHelper(ITypeMappingSource typeMappingSource) : base(typeMappingSource) + { + } + + public override bool ShouldUseFullName(Type type) + => true; // Always use fully-qualified type names +} +``` + ## Referencing Microsoft.EntityFrameworkCore.Design Microsoft.EntityFrameworkCore.Design is a DevelopmentDependency package. This means that the dependency won't flow transitively into other projects, and that you cannot, by default, reference its types. diff --git a/entity-framework/core/performance/advanced-performance-topics.md b/entity-framework/core/performance/advanced-performance-topics.md index bcd662ae1f..b081f31570 100644 --- a/entity-framework/core/performance/advanced-performance-topics.md +++ b/entity-framework/core/performance/advanced-performance-topics.md @@ -302,6 +302,10 @@ Because of these limitations, you should only use compiled models if your EF Cor If supporting any of these features is critical to your success, then please vote for the appropriate issues linked above. +### Handling compilation errors due to ambiguous type references + +When compiling models with types that have the same name but exist in different namespaces, the generated code may produce compilation errors due to ambiguous type references. To resolve this, you can customize the code generation to use fully-qualified type names by overriding `CSharpHelper.ShouldUseFullName` to return `true`. See [Design-time services](xref:core/cli/services) for information on how to override design-time services like `ICSharpHelper`. + ## Reducing runtime overhead As with any layer, EF Core adds a bit of runtime overhead compared to coding directly against lower-level database APIs. This runtime overhead is unlikely to impact most real-world applications in a significant way; the other topics in this performance guide, such as query efficiency, index usage and minimizing roundtrips, are far more important. In addition, even for highly-optimized applications, network latency and database I/O will usually dominate any time spent inside EF Core itself. However, for high-performance, low-latency applications where every bit of perf is important, the following recommendations can be used to reduce EF Core overhead to a minimum: From e26cd9a35bc81c05e1ca6768b180a9fd13efdb8c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 1 Oct 2025 00:44:48 +0000 Subject: [PATCH 6/7] Fix compilation errors in CustomTools.cs sample Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com> --- samples/core/Miscellaneous/CommandLine/CustomTools.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/samples/core/Miscellaneous/CommandLine/CustomTools.cs b/samples/core/Miscellaneous/CommandLine/CustomTools.cs index 13dc996b9c..8450b1c463 100644 --- a/samples/core/Miscellaneous/CommandLine/CustomTools.cs +++ b/samples/core/Miscellaneous/CommandLine/CustomTools.cs @@ -1,4 +1,5 @@ -using System.IO; +using System; +using System.IO; using System.Reflection; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Design; @@ -46,7 +47,7 @@ internal class MyDbContext : DbContext { protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { - optionsBuilder.UseSqlServer("Server=(localdb)\\MSSQLLocalDB;Database=MyDatabase;Trusted_Connection=true;"); + optionsBuilder.UseSqlite(@"Data Source=test.db"); } public DbSet Blogs { get; set; } From 05c6efb146719f2bf1d568b079bb4ec750b7434a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 1 Oct 2025 00:49:19 +0000 Subject: [PATCH 7/7] Remove customizing individual services section per review feedback Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com> --- entity-framework/core/cli/services.md | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/entity-framework/core/cli/services.md b/entity-framework/core/cli/services.md index 64ed70d92d..73926d4e7b 100644 --- a/entity-framework/core/cli/services.md +++ b/entity-framework/core/cli/services.md @@ -11,28 +11,6 @@ Some services used by the tools are only used at design time. These services are [!code-csharp[Main](../../../samples/core/Miscellaneous/CommandLine/DesignTimeServices.cs#DesignTimeServices)] -### Customizing individual services - -You can also override individual methods in design-time services. For example, to customize how type names are generated in scaffolded code to always use fully-qualified names (which can help avoid compilation errors due to ambiguous type references), you can override the `ShouldUseFullName` method in `CSharpHelper`: - -```csharp -public class MyDesignTimeServices : IDesignTimeServices -{ - public void ConfigureDesignTimeServices(IServiceCollection services) - => services.AddSingleton(); -} - -public class MyCSharpHelper : CSharpHelper -{ - public MyCSharpHelper(ITypeMappingSource typeMappingSource) : base(typeMappingSource) - { - } - - public override bool ShouldUseFullName(Type type) - => true; // Always use fully-qualified type names -} -``` - ## Referencing Microsoft.EntityFrameworkCore.Design Microsoft.EntityFrameworkCore.Design is a DevelopmentDependency package. This means that the dependency won't flow transitively into other projects, and that you cannot, by default, reference its types.