Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't run EF migration where DbContext connection string is set at runtime and separate project from application

I have a class library project that has a DbContext class in it that looks like this:

public DbContext() : base(ContextInitializer.GetConnectionStringName())
    {

So that the user (other programmers) can set this on their application startup when they can use my API and entities on whatever database they choose in whatever project and set the connection string then. Now I am trying to generate a migration configuration in my class library. I've tried:

Enable-Migrations -ProjectName "ClassLibraryProject" -ContextTypeName "MyDbContext" -StartUpProjectName "MyWebApp" -ConnectionString "MyConnectionString" -ConnectionProviderName "System.Data.SqlClient"

Based on other answers on here who encounter the same error, and it doesn't help. I still get:

Exception calling "SetData" with "2" argument(s): "Type 'Microsoft.VisualStudio.ProjectSystem.VS.Implementation.Package.Automation.OAProject' in assembly 'Microsoft.VisualStudio.ProjectSystem.VS.Implementation, Version=14.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' is not marked as serializable." At C:\Users\me.nuget\packages\EntityFramework\6.1.3\tools\EntityFramework.psm1:718 char:5 + $domain.SetData('project', $project) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : SerializationException

Exception calling "SetData" with "2" argument(s): "Type 'Microsoft.VisualStudio.ProjectSystem.VS.Implementation.Package.Automation.OAProject' in assembly 'Microsoft.VisualStudio.ProjectSystem.VS.Implementation, Version=14.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' is not marked as serializable." At C:\Users\me.nuget\packages\EntityFramework\6.1.3\tools\EntityFramework.psm1:719 char:5 + $domain.SetData('contextProject', $contextProject) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : SerializationException

Exception calling "SetData" with "2" argument(s): "Type 'Microsoft.VisualStudio.ProjectSystem.VS.Implementation.Package.Automation.OAProject' in assembly 'Microsoft.VisualStudio.ProjectSystem.VS.Implementation, Version=14.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' is not marked as serializable." At C:\Users\me.nuget\packages\EntityFramework\6.1.3\tools\EntityFramework.psm1:720 char:5 + $domain.SetData('startUpProject', $startUpProject) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : SerializationException

Other answers I've seen on here say use -StartUpProjectName param, and I did that but still get the error. I thought it was because my projects were in nested folders in the solution I am working in, but supplying the project names as "path/ProjectName" triggered an error that project wasn't found, so that can't be it.

EDIT: I found this: EF 6 with a dnx project, my project is Asp.NET Core class library targeting 461 runtime and being used in Asp.NET Core Web app. So there is no way to run a migration in a class library using EF 6 with ASP.NET Core?

like image 385
SventoryMang Avatar asked Oct 05 '16 21:10

SventoryMang


1 Answers

Okay, so after much looking, you can't do this by default. No tooling for class libraries since January at all, which seems horrible to me. And no tooling as the link I posted mentions for a .NET CORE class library targeted at 461 using EF6, because EF6 tools do not recognize project.json dependency format.

However, blessed be, a gentleman by the name of Mohammad Rahhal created such a library to accomplish this: https://github.com/mrahhal/Migrator.EF6/blob/master/README.md

And using the information described in this issue: https://github.com/mrahhal/Migrator.EF6/issues/9

I was able to successfully run a migration, it does require some hacky stuff, but it works for the time being, better than other alternatives provided elsewhere.

1) Download this nuget package for Migrator.EF6.Tools nuget.

2) Change project.json to include:

{
  "version": "1.0.0-*",

  "dependencies": {
    "EntityFramework": "6.1.3",
    "Migrator.EF6.Tools": "1.0.5"
  },

  "frameworks": {
    "net461": {}
  },

  "buildOptions": {
    "emitEntryPoint": true
  },

  "tools": {
    "Migrator.EF6.Tools": {
      "imports": "portable-net45+win8+dnxcore50",
      "version": "1.0.5"
    }
  }
}

3) Add a program.cs file with Main stub to the class library project:

public class Program
{
    public static void Main(string[] args)
    {
    }
}

You are now set to run migrations from VS2015 Dev Command Prompt. Navigate to the project directory, and run the migration commands described in the readme linked above.

However, it should be noted, once you are done running migrations, set emitEntryPoint value to false again so it can still be treated like a normal class library. Basically you are tricking the EF tooling to think your class library is a console app, but you don't want it to be treated like that for deployment.

like image 104
SventoryMang Avatar answered Nov 09 '22 02:11

SventoryMang