Entity Framework code first update-database fails

2019-03-11 03:23发布

问题:

This post has been noted

So has this one

On my dev machine I am trying to recreate my database using update-database from package manager console. I believe I have followed the instructions in the posts cited above.

I get this error message:

A file activation error occurred. The physical file name '\WRDatabase.mdf' may be incorrect. Diagnose and correct additional errors, and retry the operation. CREATE DATABASE failed. Some file names listed could not be created. Check related errors.

The command I am running is:

update-database -ConfigurationTypeName WRConfiguration  -ConnectionStringName localWR -Verbose

Note in the command above I am passing a connection string name and it appears the connection string is being used because the name of the .mdf file appears in the error message.

Interestingly, I am able to run my code and my database is created but it is created with the wrong name (it is named "VIN.DataModel.WRContext" which is the full namespace and class name of the DbContext). My guess is that when my code runs EF cant find the connection string for creating the database. This is intentional as I will map this context to a database that runs on a server and also to a copy of the db that runs on the local machine (i.e. I will have two connection strings for the same DbContext).

Here is app config:

<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
  <parameters>
    <parameter value="v11.0" />
  </parameters>
</defaultConnectionFactory>
</entityFramework>
<connectionStrings>
     <add name="localWR" providerName="System.Data.SqlClient" connectionString="Data Source=(LocalDB)\v11.0;Initial Catalog =WRDatabase;AttachDBFilename=|DataDirectory|\WRDatabase.mdf; Integrated Security=True;MultipleActiveResultSets=True" />
</connectionStrings>

AutomaticMigrationsEnabled is set to false in the constructor of the Configuration class.

Here is the context class:

public class WRContext : DbContext
{
    static WRContext()
    {
        Database.SetInitializer(new MigrateDatabaseToLatestVersion<WRContext, VIN.DataModel.WRMigrations.WRConfiguration>());
    }

    public WRContext()
    {

    }

    public WRContext(string connectionString)
        : base(connectionString)
    { 

    }


    public DbSet<Emp> Emps { get; set; }
    public DbSet<Inv> Invs { get; set; }
    public DbSet<WRConfig> WRConfigs { get; set; }
}  

回答1:

I found the answer here:

http://kazimnami.azurewebsites.net/techblog/2012/11/24/error-a-file-activation-error-occurred-create-database-failed/

Thank you kazim.

The exception is thrown when the "|DataDirectory|" property in the connection string is not evaluated. To solve the issue, add following line to your code:

AppDomain.CurrentDomain.SetData("DataDirectory", System.IO.Directory.GetCurrentDirectory());


回答2:

Actually you need to put the line given by OP's answer in the extended xxContext: dbContext class.

public class WRContext : DbContext
{
    public WRContext()
        : base("localWR")
    {
        AppDomain.CurrentDomain.SetData("DataDirectory", System.IO.Directory.GetCurrentDirectory());
    }
    public DbSet<Emp> Emps { get; set; }
    //....
}


回答3:

If previous answer is right its easy to set it via command line

Update-Database -AppDomainBaseDirectory C:\you-path


回答4:

For me the issue was that I moved from a (localdb) instance to a solid SQL server instance. In order to have update-database create the needed database i had to remove ;AttachDBFilename=|DataDirectory|\somedatabase.mdf

completely then everything else worked as expected



回答5:

If your doing integration tests then use a generic controller method to set the directory. See StefanG's answer.

            public static T SetupController<T>() where T : ApiController, new()
            {
                //LocalDB database to the tests directory.
                AppDomain.CurrentDomain.SetData("DataDirectory", System.IO.Directory.GetCurrentDirectory());

                var request = new HttpRequestMessage();

                var config = WebApiConfig.SetupRegister(new HttpConfiguration());

                var controller = new T()
                {
                    Request = request,
                    Configuration = config
                };

                return controller;
            }