Ef6: Make EF NuGet package / migrations and EF Tools work with new csproj format

Created on 24 Mar 2017  Â·  40Comments  Â·  Source: dotnet/ef6

Workaound:

Currently the following workaround works (tested on an ASP.NET Core 2.0 app):

  • Move the model into a traditional .NET Framework library that uses the old project system
  • Add the aforementioned library as a dependency
  • Unload the ASP.NET Core application from the solution
  • Execute the Enable-migrations command against the library project. This step seems to only be necessary the first time, otherwise you will get an error saying:

Exception calling "SetData" with "2" argument (s): "Type 'Microsoft.VisualStudio.ProjectSystem.VS.Implementation.Package.Automation.OAProject' in assembly 'Microsoft.VisualStudio.ProjectSystem.VS.Implementation, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' is not marked as serializable."

  • Re-load the ASP.NET Core project
  • Work as normal, with migration commands always pointing to the .NET Framework library project

Options:

We could consider

  1. Doing the full work to enable EF6 migrations to work with the new project system (which would likely be very expensive)
  2. Improve EF6 migrations to handle the presence of projects using the new project system more gracefully, e.g.:

    1. It would be nice if we provided a nice error which provided guidance on creating a separate project

    2. Once a customer applies the workaround, it would be nice if they didn't need to unload the ASP.NET Core project

Original issue:

See https://github.com/aspnet/EntityFramework6/issues/230 and https://github.com/aspnet/EntityFramework6/issues/189 and https://github.com/NuGet/Home/issues/4876

See also _New csproj format and GenerateSeparateFiles=true causes VS2017 to freeze https://github.com/sjh37/EntityFramework-Reverse-POCO-Code-First-Generator/issues/266_ which blocks EF Tools tt codegen with the new csproj files.

closed-fixed type-enhancement

Most helpful comment

@ajcvickers Any progress made on this yet?

The current state of things between .NET 4.7 and EF6.2, and Azure dropping support for .NET Core < 2.0.4... making living in the ecosystem unworkable. We need this EF6 situation fixed (ie: adoption of it as 1st class citizen by the team).

All 40 comments

Hi,
I am with a system that has migrated from VS2015 (net461) to VS2017 (csproj "net461"), with problem equal ao @HellBrick.#230

Do you have prevision to new version EF 6.3.2 ?
Is there any workaround I can do for now?

I'm also having this issue in EF 6.1.3 in a WebAPI + Xamarin PCL.
Unable to execute PM> Enable-Migrations -ProjectName MyWebAPI, a NullReferenceException is thrown internally.

I get the following exception:

>

PM> enable-migrations -projectname mywebapiprojectname
Exception calling "SetData" with "2" argument(s): "Type 'Microsoft.VisualStudio.ProjectSystem.VS.Implementation.Package.Automation.OAProject' in assembly 
'Microsoft.VisualStudio.ProjectSystem.VS.Implementation, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' is not marked as serializable."
At C:\Users\Shimmy\.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=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' is not marked as serializable."
At C:\Users\Shimmy\.nuget\packages\entityframework\6.1.3\tools\EntityFramework.psm1:719 char:5
+     $domain.SetData('contextProject', $contextProject)
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : SerializationException

System.NullReferenceException: Object reference not set to an instance of an object.
   at System.Data.Entity.Migrations.Extensions.ProjectExtensions.GetPropertyValue[T](Project project, String propertyName)
   at System.Data.Entity.Migrations.MigrationsDomainCommand.GetFacade(String configurationTypeName, Boolean useContextWorkingDirectory)
   at System.Data.Entity.Migrations.EnableMigrationsCommand.FindContextToEnable(String contextTypeName)
   at System.Data.Entity.Migrations.EnableMigrationsCommand.<>c__DisplayClass2.<.ctor>b__0()
   at System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command)
Object reference not set to an instance of an object.

OMG so no migrations until 6.3? Any roadmap/workaround?

@weitzhandler Migrations works now, just not with the new csproj infrastructure. Is there something that is stopping you using the traditional project system?

Just use the existing project system

@ErikEJ @ajcvickers thanks for your reply, I probably got it wrong. What do you guys refer to when saying 'traditional project system'? This project was created in VS2017, and it's a csproj.
Since it's an existing project, is there anything I can change to make it 'traditional'?
Again, thanks in advance!

@ErikEJ @ajcvickers I have the same question as @weitzhandler. When you say traditional/existing project system, do you mean VS2015 (net461), or simply VS2017 with the old project.json project file?

@Shloosh
I think the new project system refers to the one created in .NET Standard projects.
The extension remains _.csproj_, but the file structure is much cleaner and easier to edit.
@ErikEJ, correct?

Correct

@divega
Are you ever going to support inline migrations support for ASP.NET Core + EF 6.1.3?

@weitzhandler can you please explain exactly what you mean with that? Sorry if it can be inferred from the context above, but I haven’t read the whole thread.

@divega
It's impossible to run EF 6.1.3 migrations in an ASP.NET Core project with the new project format.
When you run the command enable-migrations you get an internal NullReferenceException, see the full error in my comment above.
Are you ever going to address this?
Although we like adopting new technologies, unfortunately EFCore lacks some crucial features (i.e. TPT) we decided to wait until those are implemented.

@weitzhandler thanks for clarifying.

I don't think we can answer that yet. Our main strategy for ASP.NET Core and .NET Core in general is to make EF Core a very compelling solution, but that includes closing some of the feature gaps with EF6, as you point out, and that is going to take a few releases.

On the flips side, working with EF6 in an ASP.NET Core application is possible but requires workarounds. E.g. in this case, keep the model in a separate .NET Framework library with a traditional project file, and unload any projects from the solution that use the new project system while working with migrations.

We are reluctant to commit to making EF6 migrations fully work with the new project system because we believe that would involve a significant investment which would hinder our progress on our main strategy, but perhaps there are less expensive things we can do to reduce the friction of the workarounds, e.g. make it so that you still need to put the EF6 model in a separate project but at least you don't need to unload other projects.

Does that make sense?

...keep the model in a separate .NET Framework library with a traditional project file, and unload any projects from the solution that use the new project system while working with migrations.

This is one of the main reasons I won't touch the new project system (or even .net core really). The lack of on parity tooling means it adds more headaches than it solves. Not to mention the new project system shines when doing things like EF migrations because of all the files that are added. So realistically the projects that benefit from it the most (EF and websites) don't support it and negate moving anything to it.

I have updated the original issue to explain some of the options.

In my current scenario moving the model to a separate assembly is not an option. The models have partial classes that are ASP.NET specific.
Of course I'd be happy going the Core way totally and leave the old versions behind. As I pointed out TPT is my barrier with EF (complex types was too), and it's not even been assigned a milestone https://github.com/aspnet/EntityFrameworkCore/issues/2266.

BTW @divega this repo helped me get my project to work with migrations.

For 6.3, we will look at what it would take to allow the tools to not crash if other project types are present in the solution. (Note that this is different from allowing the projects to be used as a target for EF commands.)

@divega @ErikEJ for the workaround you do NOT need to actually unload the new project,
just set it as the startup project and as the default project in the package manager (yes this sounds as stupid as it looks but it works, trust me i'm a software engineer)

In my testing (with automatic migrations disabled, EF6.2.0, VS2017 15.5.x),
i only need to have the Context and migrations in the legacy project,
all my data classes can be in a new style .net standard project (with <TargetFrameworks>net461;…)

@KLuuKer Thank you! I have my Web project as the "Startup Project" (for obvious reasons). Setting my "Core" project (which contains all the back-end and DB-related code) as the "Startup Project" helped "fix the glitch" with respect to EF-related commands.

Just discovered: You may skip right-clicking the project and setting it as the startup project if you add the -StartupProjectName {project_name} option to your EF command in Package Manager Console. I really only use Update-Database and Add-Migration, so these two would then be:

EntityFramework\Update-Database {options} -StartupProjectName {project_name} or
EntityFramework\Add-Migration -Name {name} -StartupProjectName {project_name}

@ajcvickers Any progress made on this yet?

The current state of things between .NET 4.7 and EF6.2, and Azure dropping support for .NET Core < 2.0.4... making living in the ecosystem unworkable. We need this EF6 situation fixed (ie: adoption of it as 1st class citizen by the team).

Please after 1 year is there any news? Do we have a 6.3 package somewhere we can try?

@cvrtaw
EF 6.3 will be officially supported in .NET Core apps (Read this comment by @ajcvickers).

This is unworkable. We really need a fix for this.

Actively working on it. I hope to get something into 6.3.0-preview7 (the July preview)

Work to make the PMC commands (Add-Migration, Update-Database, etc) compatible with .NET Core 3.0 projects is well underway. Unfortunately, nothing made it into 3.6.0-preview7, but it's on track for Preview 8 (August).

On a related note, do we also need a dotnet ef6 command? I'm splitting it out into issue #1053 since it's unclear how important it is to do as part of 6.3.0. Take a look at that issue and upvote/comment if you have an opinion.

@bricelam a strong YES. How unclear is it that migrations are pivotal to running 6.3.0?

You can't responsibly run databases without migrations. It is CORE to them, literally the same as asking can/should you develop without a code repository. How is that even a question?

@marchy I think you misread my last comment. Migrations commands WILL work in 6.3.0.

@bricelam if that's the case then my apologies. I understood it as contemplating whether support for EF 6 migrations should be warranted (VS just EF Core), rather than maintaining support for @mrahhal's Migrator.EF6's project which has been filling the stop-gap prior to the upcoming official support.

To clarify, will the EF6 migration commands be user-invocable (ie: as simple as dotnet ef6 database update)? #1053 seems to indicate this isn't the case. In which case the comment above is still a strong YES – but hopefully provided by the official CLI not from Migrator.EF6.

We don't use Visual Studio at all (use Rider instead) and have always used the terminal/CLI for migration commands even when VS was part of our toolset.

Thanks for your clarifications around this.

Yes, this issue is about making the existing EF6 Migrations commands (Update-Database, Add-Migration, etc.) work with .NET Core (aka SDK-style) projects. My latest PR (#1058) completes this work.

image

I have an exception while adding migration.
Newly created two projects:
- TestEF6 - ASP.Net Core Web Application (targets .Net Core 3.0 preview6);
- ClassLibrary1 - Class Library Project (targets .Net Core 3.0 preview 6).
ClassLibrary1 uses EF 6.3 preview 6.
Visual Studio 2019 with the latest updates.

Full text of the error:
`Exception calling "SetData" with "2" argument(s): "Type 'Microsoft.VisualStudio
.ProjectSystem.VS.Implementation.Package.Automation.OAProject' in assembly 'Mic
rosoft.VisualStudio.ProjectSystem.VS.Implementation, Version=16.0.0.0, Culture=
neutral, PublicKeyToken=b03f5f7f11d50a3a' is not marked as serializable."
At C:UsersRoman from Ryasne-2.nugetpackagesentityframework6.3.0-preview6-
19304-03toolsEntityFramework.psm1:720 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 'Mic
rosoft.VisualStudio.ProjectSystem.VS.Implementation, Version=16.0.0.0, Culture=
neutral, PublicKeyToken=b03f5f7f11d50a3a' is not marked as serializable."
At C:UsersRoman from Ryasne-2.nugetpackagesentityframework6.3.0-preview6-
19304-03toolsEntityFramework.psm1:721 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 'Mic
rosoft.VisualStudio.ProjectSystem.VS.Implementation, Version=16.0.0.0, Culture=
neutral, PublicKeyToken=b03f5f7f11d50a3a' is not marked as serializable."
At C:UsersRoman from Ryasne-2.nugetpackagesentityframework6.3.0-preview6-
19304-03toolsEntityFramework.psm1:722 char:5

  • $domain.SetData('startUpProject', $startUpProject)
  • ~~~~~~~~~~

    • CategoryInfo : NotSpecified: (:) [], MethodInvocationException

    • FullyQualifiedErrorId : SerializationException

System.NullReferenceException: Object reference not set to an instance of an object.
at System.Data.Entity.Migrations.Extensions.ProjectExtensions.GetPropertyValueT
at System.Data.Entity.Migrations.MigrationsDomainCommand.GetFacade(String configurationTypeName, Boolean useContextWorkingDirectory)
at System.Data.Entity.Migrations.AddMigrationCommand.Execute(String name, Boolean force, Boolean ignoreChanges)
at System.Data.Entity.Migrations.AddMigrationCommand.<>c__DisplayClass1_0.<.ctor>b__0()
at System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command)
Object reference not set to an instance of an object.`

Please, ask for more information if needed.

@RomanHubyak This issue was not fixed for preview 6. The first preview that contains this fix will be preview 8. Or you should be able to try it now using the nightly builds.

@bricelam the migrations commands still don't work in EF 6.3 / .NET Core 3.0 Preview 9 + Visual Studio 2019 16.3.0 Preview 3.

Running from the Package Manager Console, getting the following error when targeting a newly-updated nestandard2.1 project:

PM> get-migrations
Project 'Libraries\World.NET.Data' targets framework '.NETStandard'. The Entity Framework Package Manager Console Tools don't support this framework.

We missing something?

@marchy .NET Standard projects are not supported--only .NET Core projects. Can you submit a new issue requesting support for these?

The reason is that there is no runtime associated with .NET Standard--it's just a spec/interface--so we can't execute the code to build your model. We've mitigated this on EF Core by executing code through the startup project. This lets you put your DbContext in a .NET Standard class library so long as you have a .NET Core app referencing it that you can use to execute code. We didn't want to break existing workflows by dramatically changing the way the commands execute your code to build the model. However, I'm sure we can find a non-breaking way to enable this if there is sufficient demand.

Out of curiosity, in what other frameworks besides .NET Core 3.0 are you using your .NET Standard 2.1 library?

I'm struggling with this and I wonder if anyone could help. I have a solution, with a WebApi and a class library (there are many more projects but they are irrelevant to this) which contains the EF code (Context, Migrations Entities and so on). All projects are running on .NET Framework 4.7.2. No .NET Core involved here.

I'm currently migrating all projects to the new SDK .csproj style and the only ones left are the WebApp (will not migrate for now) and the EF class lib.

I assumed that with the latest bits (6.3.0-preview9-19423-04) I would be able to migrate the project which contains the EF code to the new format, and would be able to work normally with migrations, but it's not working. Am I just wrong in my assumption or?

I simply run this, as I normally do

Update-Database -connectionstring "..." -connectionprovidername "System.Data.SqlClient" -StartUpProject "ClassLibProject" -ProjectName "ClassLibProject"

And the error it gives me is:

image

Tried running with the old tools, also doesn't work. Do I need to add anything special in my .csproj file, in order for this to work? I tried searching for examples but couldn't find any.

@joaopgrassi Does -Verbose give any additional information? Could you submit a new issue with a simplified repro so that we can investigate?

Hi, @bricelam. I started creating a repro and there it worked. So, I went to my project and did the same steps and it worked. Not sure what was up. But I faced a new problem along the way. Will submit a new issue. Thanks!

@bricelam still doesn't work even if running it in context of referencing projects.

Running from both a ASP.NET Core 3.0 web app and a .NET Core 3.0 console app, error is:

PM> get-migrations
Retrieving migrations that have been applied to the target database.
No migrations configuration type was found in the assembly 'Xxx.xxx.Server'. (In Visual Studio you can use the Enable-Migrations command from Package Manager Console to add a migrations configuration).

All 3 projects (library, console app, web app) have just been upgraded to RC1 and issuing the migration commands from the new Visual Studio 16.3.0 Preview 4.0.

I ran into the very same issue when using a .Net Framework app with the new SDK project format. To fix, it was enough to upgrade Entity Framework to version 6.4 (I guess anythign 6.3+ will work).

the absence of BindingRedirects can cause problems. Such as:

System.IO.FileLoadException: Could not load file or assembly '...

To resolve, ensure you are on EF 6.4, then try Enable-Migrations -Verbose and you should see the command line containing ef6.exe printed out. What happened is the --config is passed the original App.config which now has no more binding redirects in it.

You can workaround it by manually calling EF6.exe and passing the .config of the built assembly.

C:\users\.nuget\...\ef6.exe ... --config bin\Debug\net462\My.Migration.dll.config
Was this page helpful?
0 / 5 - 0 ratings