Set DatabaseInitializerForType in config file for

2019-07-14 22:25发布

问题:

So I either get errors firing or nothing happens. I know that I have custom Entity Framework Initializer like this:

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EasyEntity
{
    public class EasyInitializer : DropCreateDatabaseAlways<EasyContext>
    {
        protected override void Seed(EasyContext context)
        {
            List<Person> persons = new List<Person>
            {
                new Person { FirstName = "Waz", LastName = "Amattau"},
                new Person { FirstName = "Helena", LastName = "Handbasket"},
            };

            foreach (var person in persons)
                context.Person.Add(person);

            base.Seed(context);
        }
    }
}

I can call this when I set this quite easily:

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EasyEntity
{
    public class EasyContext : DbContext
    {
        public EasyContext() : base("name=EasyEntity")
        {
            Database.SetInitializer<EasyContext>(new EasyInitializer());   
        }

        public DbSet<Person> Person { get; set; }
    }
}

Yet this is all in a class library and when I have a console app to test this it will not fire in the app.config. I am ultimately looking to create builds or what not or apps to fire or not fire based on environment. After scouring the internet it seems many different people label and put different text in this config setting. I am using Entity Framework 6.1.3 according to NuGet, yet the config and references claim 6.0.0 and have wondered if this has changed and how to make it fire from a seperate project without having to hardcdoe the intializer to fire. I have this:

<appSettings>
    <add key="DatabaseInitializerForType EasyEntity.EasyInitializer, EasyEntity" value="true" />
  </appSettings>

I have tried setting 'value' to lots of things like 'Enabled', 'EasyEntity.EasyInitializer, EasyEntity', 'true', 'comeonpleasefire'. But nothing appears to work as I am ignorant of what to do. I saw another blog putting the setting inside the entityFramework node in the config section but that did not work either. My total config setting in my console app for reference:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
  <appSettings>
    <add key="DatabaseInitializerForType EasyEntity.EasyInitializer, EasyEntity" value="true" />
  </appSettings>
  <connectionStrings>
    <add name="EasyEntity" providerName="System.Data.SqlClient" connectionString="Server=.;Database=Easy;Integrated Security=True;"/>
  </connectionStrings>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="Data Source=.; Integrated Security=True; MultipleActiveResultSets=True" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>
</configuration>

回答1:

Entity Framework doesn't pick up values from the appSettings section of your application configuration file. Instead you need to use entityFramework.contexts.context.databaseInitializer section, something like this should do it:

  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="Data Source=.; Integrated Security=True; MultipleActiveResultSets=True" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
    <contexts>
        <context type="EasyEntity.EasyContext, EasyEntity">
            <databaseInitializer type="EasyEntity.EasyInitializer, EasyEntity" />
        </context>
    </contexts>
  </entityFramework>


回答2:

EF does not run the initializer until you use the the context or explicitly tell EF to create the db.

Try this in you console application

using (var context = new EasyContext ())
{
    // Uncomment this line to see the raw sql commands
    //context.Database.Log = Console.WriteLine;
    context.Database.CreateIfNotExists();
    context.Database.Initialize(true);
}


回答3:

To Answer the original question you can set the Initializer in the appSettings. You can use reflection to set the Initializer like so:

<appSettings>
<add key="DatabaseInitializerForType EasyEntity.EasyContext, EasyEntity" value="System.Data.Entity.DropCreateDatabaseAlways`1[[EasyEntity.EasyContext, EasyEntity]], EntityFramework" />

You may have been confused by 'disabled' with the answer far different than setting it to 'enabled' or 'true'. If you want to run a 'seed' method you could use access the initializer class with the following.

<appSettings>
<add key="DatabaseInitializerForType EasyEntity.EasyContext, EasyEntity"  value="EasyEntity.EasyInitializer, EasyEntity" />