Database.SetInitializer for null not working Entity Framework 4.3.1 Code First

I have a context class that inherits from the abstract base AuditableDbContext : DbContext . AuditableDbContext takes two parameters: one for the auditor and one for the context for the audit.

In the inherited class, I have a default parameterless constructor that calls other constructors with zero parameters, and then in the final constructor I call Database.SetInitializer<MyDbContext>(null) after calling the base constructor.

The problem is that even when I do this, I still get db migration calls to the database server when the application starts.

 public abstract class AuditableContext : DbContext { public AuditableContext(IAuditor auditor, DbContext auditContext) { // params can be null resulting in no auditing // initialization stuff here... } } public class MyDbContext : AuditableContext { // DbSets here... public MyDbContext() : this(null, null) {} public MyDbContext(IAuditor auditor) : this(auditor, null) {} public MyDbContext(IAuditor auditor, DbContext auditContext) : base(auditor, auditContext) { Database.SetInitializer<MyDbContext>(null); } } 

The queries I see in the database are two common migration requests ...

 SELECT [GroupBy1].[A1] AS [C1] FROM ( SELECT COUNT(1) AS [A1] FROM [dbo].[__MigrationHistory] AS [Extent1] ) AS [GroupBy1] SELECT TOP (1) [Extent1].[Id] AS [Id], [Extent1].[ModelHash] AS [ModelHash] FROM [dbo].[EdmMetadata] AS [Extent1] ORDER BY [Extent1].[Id] DESC 

Any ideas on how to stop the Entity Framework from executing these queries?

+4
source share
2 answers

You will need to do this in a static constructor, or better yet, PRIOR to create the context.

 static MyDbContext() { Database.SetInitializer<MyDbContext>(null); } 
+11
source

Sorry to answer such an old question, especially the one marked as the answer, but it haunted me and I wanted to offer a solution independently.

The problem is that LINQPad creates a subclass of the DbContext class. So when you call Database.SetInitializer<MyDbContext>(null) , this will work as long as you create an instance of MyDbContext. But by design, LINQPad compiles your code into a class that comes from MyDbContext. If you make MyDbContext sealed, LINQPad will not be able to use it.

The workaround is to use reflection to invoke Database.SetInitializer in the constructor of the MyDbContext instance. This means that you unnecessarily invoke it for each instance of the context, but that won't hurt anything. But this allows you to use this.GetType () to access the subclass that LINQPad creates, and then you can use reflection to call SetInitializer .

It would be nice if a non-generic version of the method were added.

This Gist has an example of using reflection to invoke Database.SetInitializer .

 var databaseType = typeof( Database ); var setInitializer = databaseType.GetMethod( "SetInitializer", BindingFlags.Static | BindingFlags.Public ); var thisType = GetType( ); var setInitializerT = setInitializer.MakeGenericMethod( thisType ); setInitializerT.Invoke( null, new object[] { null } ); 
+9
source

Source: https://habr.com/ru/post/1482498/


All Articles