dotnet / efcore

EF Core is a modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations.
https://docs.microsoft.com/ef/
MIT License
13.66k stars 3.15k forks source link

Guidance: How to use EF6 with ASP.NET Core 1 RC2 web app? #2336

Closed ToddThomson closed 1 year ago

ToddThomson commented 9 years ago

I've been moving a subset of my MVC 5, EF6 application to ASP.NET 5, MVC 6 and EF7 and I really like the direction that the platform is moving to. Moving to EF7, however, poses many issues for me. It is just too short on required features that I have used in EF6. I feel I will be investing a great deal of time to add workarounds and to deal with the limitations. So, what is the guidance for using EF6 with an ASP.NET 5 application? I have my database services and repository code in separate libraries (I have essentially a dll for each derived type + a dll for a base type ). Any help would be very much appreciated!

ErikEJ commented 9 years ago

@julielerman has an article in the latest MSDN magazine on how to do that!

mundi4 commented 9 years ago

in project.json:

    "dependencies": {
        "EntityFramework": "6.1.3"
    },
    "frameworks": {
        "dnx451": {
            "frameworkAssemblies": {
                "System.Data": "4.0.0.0"
            }
        } //, "dnxcore50": { }
    }
julielerman commented 9 years ago

Here's a link to the article: https://msdn.microsoft.com/en-us/magazine/dn973011.aspx.

Separation of Concerns is your friend here. Just have your data access (EF) stuff with EF6 in its own project (or projects if you ahve multiple models).

HTH (& thanks @ErikEJ )

ToddThomson commented 9 years ago

Thanks @ErikEJ and @julielerman ! I've just finished reading through your article. It cleared up a bit of confusion on the project.json use of the "frameworks" property. I really have no need for dnxcore50 at the moment so I've just removed that framework. I want to point out that I need a dependency on MVC 6 and a few other ASP.NET 5 bits from within my ASP.NET 5 class library as well the EF6 dependency. So I just added "EntityFramework": "6.1.3" into the project.json. This seems to work. I am not sure about migrations and using EF6 with visual studio 2015 RC, but hopefully that will work too. Lastly, by keeping your service and repository code in separate class libraries it should be possible to use EF7 and Identity 3 as long as it too is walled in a separate library.

ToddThomson commented 9 years ago

@mundi4 Just saw your post - that's exactly what I did. Thanks.

rowanmiller commented 9 years ago

Lastly, by keeping your service and repository code in separate class libraries it should be possible to use EF7 and Identity 3 as long as it too is walled in a separate library.

I don't think that is true because you can't have two different versions of the same assembly loaded in an AppDomain. BTW there is some discussion on an EF6 provider for ASP.NET 5 Identity which would solve this issue https://github.com/aspnet/Identity/issues/416.

ToddThomson commented 9 years ago

@rowanmiller Thanks. I was just about to test it out. I'll edit my post above.

ToddThomson commented 9 years ago

I've determined that the powershell scripts to enable migrations (etc) in the EF6 6.1.3 nuget package are not installed when the web application project type is the new ASP.NET 5 XPROJ type. I can understand the reasoning behind this. However, as I mentioned in the starting post for this issue, I cannot use EF7 due to its lack of features compared to EF6. Is there a chance that the DNX team and the EF team can come together to provide ASP.NET 5 XPROJ + EF6 migrations support?

rowanmiller commented 9 years ago

@ToddThomson at this stage the ASP.NET 5 xproj system does not process the PowerShell files that can be included in a NuGet package. If you want to add your vote toward this feature then here is the place to do so https://github.com/aspnet/dnx/issues/952.

rowanmiller commented 9 years ago

@ToddThomson

I cannot use EF7 due to its lack of features compared to EF6

What features in particular are blocking you from using EF7? I'd like to understand if they are things that will be implemented by the initial RTM of ASP.NET 5 and EF7 or whether they are things that will still be missing once we move beyond pre-release.

ToddThomson commented 9 years ago

@rowanmiller The things that I believe are blocking me from porting my MVC5, EF6 content management system to EF7 are: 1) Custom Convensions:

public class UnmapCoreEntitiesConvention : Convention
    {
        public UnmapCoreEntitiesConvention()
        {
            Types()
                .Where( t => t.CustomAttributes.Any( n => n.AttributeType == typeof( CoreContentEntity ) ) )
                .Configure( config => config.Ignore() );
        }
    }

2) Many to Many

protected override void OnModelCreating( DbModelBuilder modelBuilder )
        {
            modelBuilder.Entity<ContentBase>()
                .HasMany( e => e.Tags )
                .WithMany( e => e.ContentBase )
                .Map( m => m.ToTable( "cms_ContentBaseTags" ).MapLeftKey( "ContentId" ).MapRightKey( "TagId" ) );

            // Remove all contentBase derived types

            modelBuilder.Conventions.Add<UnmapCoreEntitiesConvention>();
        }

3) TPT Inheritance: In my CMS, every content type inherits from ContentBase ( all content types along with their services and repositories are in separate dlls )

I hope that helps.

rowanmiller commented 9 years ago

@ToddThomson I'll come back to the features in the next couple of days 1 and 2 are possible but the code looks a little different. 3 is not possible at the moment.

I've determined that the powershell scripts to enable migrations (etc) in the EF6 6.1.3 nuget package are not installed when the web application project type is the new ASP.NET 5 XPROJ type

I think you will be able to manually run Init.ps1 from the EntityFramework NuGet package (in the packages folder) from Package Manager Console to load the commands. I haven't tried it yet, so I'm not sure if it works... thought I'd mention it in case you want to experiment with it before I get a change to.

ToddThomson commented 9 years ago

@rowanmiller Thanks. I'll try the manual install later today.

ToddThomson commented 9 years ago

@rowanmiller A simple way to get EF6 commands to work in an ASP.NET 5 XPROJ solution is to add an empty CPROJ project and add EF6 6.1.3 nuget package to both. At that point you can run enable-migrations, etc ( EF6 commands ). When targeting the ASP.NET 5 project, the commands fail with:

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.0.0.0, Culture=neutral, 
PublicKeyToken=b03f5f7f11d50a3a' is not marked as serializable."
At C:\src\temp\WebApplication5\packages\EntityFramework.6.1.3\tools\EntityFramework.psm1:730 char:5
+     $domain.SetData('project', $project)
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : SerializationException

The code at that location is:

    $domain = [AppDomain]::CreateDomain('Migrations', $null, $info)

    $domain.SetData('project', $project)
    $domain.SetData('contextProject', $contextProject)

I'll investigate a bit more, but it looks like a dead end.

rowanmiller commented 9 years ago

Looping in @cherrydev as I am told they have already looked at enabling migrations in EF6/ASP.NET5 scenarios. They may be able to share some of their finding here.

rowanmiller commented 9 years ago

@ToddThomson

Regarding the features you mentioned...

1) Custom Conventions

We may introduce an API similar to what we had in EF6. But because we changed the model builder to construct the model as it goes (rather than at the end based on the config you supplied) you can query the model and configure based on it's current shape.

i.e. this code achieves what your sample did on EF6

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            foreach (var type in modelBuilder.Model.EntityTypes)
            {
                if(type.ClrType.CustomAttributes.Any(n => n.AttributeType == typeof(CoreContentEntity)))
                {
                    modelBuilder.Ignore(type.ClrType);
                }
            }
        }

2) Many to Many

You can still model the many:many pattern, you just need to have the join entity be part of your entity model (i.e. you would have a ContentBaseTag entity). In the future we will probably just allow you to put this entity in shadow state, so the join entity is still part of your model... you just don't have to have a CLR class for it.

3) TPT

Correct that this isn't supported yet. If modifying the core table was a possibility then we are introducing support for TPH at the moment.

yashvit commented 9 years ago

Are we looking at a production release of EF7 along with VS2015? I'm looking at migrating an existing production MVC4 + EF6 project to vNext. If EF7 isn't coming out soon and EF 6 isn't fully compatible with new VS then I might as well wait a little longer before I migrate.

rowanmiller commented 9 years ago

@yashvitnaik EF7 will become RTM at the same time as ASP.NET 5 (MVC6). Neither of these will be at the same time as VS2015 RTM (both will still be preview in the VS2015 RTM). The ASP.NET team is working on making their dates public.

ToddThomson commented 9 years ago

@rowanmiller TPT is a must have for me to use EF7. I've investigated the alternatives, but I can't make TPH or TPC work. Thank-you for guidance concerning 1 and 2 above.

I'll come back to using EF6 and ASP.NET 5 when VS 2015 goes RTM. My hope is that EF6 migration commands will work and that there will be an identity 3 with an EF6 component dependency.

rowanmiller commented 9 years ago

@ToddThomson we actually just took a series of package/assembly renames so you will be able to have EF6/EF7 running in the same app (so you can use Identity 3 and still use EF6 for your data access).

ToddThomson commented 9 years ago

@rowanmiller Perfect. Is TPT on the radar for EF7?

Edit: This is all good, but vs2015 not being able to run EF6 migration commands will be trouble ( which is the case right now ).

rowanmiller commented 9 years ago

@ToddThomson not for the initial RTM. We will evaluate after that to see what we want to support beyond TPH for EF7.

ToddThomson commented 9 years ago

@rowanmiller For SxS scenario, I can have a VS2015 ASP.NET 5 xproj which has dependencies on EF6 and EF7. The problem is that the power shell scripts for EF6 ( migrations ) only work with csproj projects. Are the EF6 migrations going to be updated to support vs2015 ASP.NET 5 xproj type?

ToddThomson commented 9 years ago

Perhaps dnx . ef6 ... EntityFramework6.Commands for xproj type.

cherrydev commented 9 years ago

I have EF6 migration commands working in DNX but I've repeatedly asked for someone with commit access in ASPNET for help actually getting them into a public repository and haven't yet gotten a solid response.

ToddThomson commented 9 years ago

@cherrydev Given the recent changes to have EF6 and EF7 SxS, hopefully the ASP.NET 5 team will be more receptive to EF6 migrations working with DNX. Do you have a GitHub repository for your EF6 DNX migration commands?

rowanmiller commented 9 years ago

@ToddThomson @cherrydev xproj is going to support loading commands in Package Manager Console, so the EF6 commands will start working.

ToddThomson commented 9 years ago

@rowanmiller Thanks. Is the xproj support for EF6 commands in vs2015RTM?

rowanmiller commented 9 years ago

@ToddThomson no it will be enabled later (prior to xproj/ASP.NET 5 RTM)

cherrydev commented 9 years ago

@ToddThomson No, not a public one at the moment, but I suppose I really should.

divega commented 9 years ago

@cherrydev I think DNX command line support for EF6 is still somewhat interesting. It is just not something that belongs naturally in our plans. Sorry if that felt like lack of responsiveness. It would be great if you ship it on your own.

cherrydev commented 9 years ago

Personally, I feel like adding native DNX command line support for EF6 migrations would probably be cleaner than shoehorning Package Manager Console support in, but if that's the route that's decided upon, I'm not going to commit to maintaining a DNX command line repository for EF6 by myself, which is somewhat rough at the moment anyway. I could understand if it were simply a matter of porting the Package Manager Console command infrastructure to DNX and then just running the existing PowerShell commands on top of it, but when I was looking into it, I saw that the PowerShell commands relied heavily on the the exact structure of the .csproj style projects. If you have to re-write or heavily modify them anyway, why not just do them as native DNX commands? It's all just a wrapper around DbMigrator and MigrationScaffolder anyway. Anyway, I'm sure you must have something in mind to have decided on the other route.

ToddThomson commented 9 years ago

@cherrydev :+1: Although I agree ( understand ) with @divega , I think that devs that are not using visual studio and who are not yet able to move from EF6 to EF7 would welcome your DNX command line support for EF6 migrations.

divega commented 9 years ago

It is just not something that belongs naturally in our plans

@cherrydev @ToddThomson Actually, let me tell that back for now. We need to have a discussion about it and will come back to you.

ToddThomson commented 9 years ago

@rowanmiller You wrote:

@ToddThomson @cherrydev xproj is going to support loading commands in Package Manager Console, so the EF6 commands will start working.

I'm reviewing the progress make in Beta 7 and was wondering if this is still something that is or will be supported.

Also, is there any documentation or notes on the EF7 model builder API?

ToddThomson commented 9 years ago

@rowanmiller is EF6 and EF7 SxS still a possibility? ( Using EF7 only for Identity ).

rowanmiller commented 9 years ago

@ToddThomson PMC in xproj is still planned for our initial stable release (it requires changes by NuGet and xproj tooling team). The work has not been done yet though.

Unfortunately SxS is not possible, we were pushing some renames to make it possible but after much community feedback we reverted back to the old naming.

ToddThomson commented 9 years ago

@rowanmiller Thanks Rowan. I really appreciate your quick feedback. The asp.net 5 team is really doing a great job!

My preference right now is to try to find a way to make EF7 work for my application. I can't use TPH inheritance ( can't get my head around the denormalized schema and I have to many subtypes ), so I'm not quite sure how I'll deal with inheritance with EF7. Solving Inheritance and many-many pattern and I should be good!

cherrydev commented 9 years ago

Keep in mind @ToddThomson that a '1.0' release for ASPNET5 is not expected to correspond to a version of EF7 that is intended as a general-purpose replacement for the functionality of EF6 and if you want to use Identity 3.0, you can do that with EF6 without too much trouble. Really, the biggest hassle was dealing with the fact that EF7 can use types with type parameters (generics) as entities and EF6 does not, requiring you to make concrete sub-classes for TRole, TUserRole, TRoleClaim etc. I pretty much just copy and pasted RoleStore and UserStore from the EF7 implementation and tweaked it for EF6.

staff0rd commented 8 years ago

@cherrydev are you able to share your migration solution?

I have EF6 working in Identity 3 here but I need my DataContext library that references this to be an xproj - due to Identity 3 targeting DNX only.

Unfortunately when I convert my library to xproj, I lose migrations.

staff0rd commented 8 years ago

Seems like this was the piece of the puzzle I was missing.

Gillardo commented 8 years ago

I have tried EF7, loved it, but it aint complete enough for me either. Features missing for me were

  1. Many to many (I know currently there is a workaround, but too much work in project to use this)
  2. Complex Types. This ain't currently working for me.
  3. Configuration Files. I got round this myself, by creating an interface on my "old" configuration files and using reflection, loading all of these types.

Dont think personally that EF7 will be "ready" unless these features are complete. But love the work so far in implementing EF7 on .NET5 project, so keep up the good work.

ToddThomson commented 8 years ago

@rowanmiller You wrote that PMC in XPROJ is still planned for our stable release ( tooling support required ). For those of us who prefer to continue to use EF6.x with ASP.NET 5, is this definitely going to be supported? Now that beta 8 is out ( which is feature complete ) I would like to get started on my application rewrite. However, if EF6 is not going to be completely supported I need to also know.

cherrydev commented 8 years ago

Well, I'm still waiting to hear back from @divega about if I would have any support maintaining my EF6 migration support commands. Last I heard they were discussing how they wanted to handle it.

ToddThomson commented 8 years ago

@rowanmiller I'm going to break out the repository layer in my MVC components to a separate csproj project layer so that I can stay with EF6 and utilize the EF6 PMC. Since EF6 and EF7 cannot be used together I'll just stick with Identity 2.x.

rowanmiller commented 8 years ago

@ToddThomson we did rename the EF7 EntityFramework.SqlServer assembly/package to EntityFramework.MicrosoftSqlServer so that you will be able to use EF6/EF7 side-by-side in the same app. This wasn't in Beta 8 though, so you'd need to use a nightly build or wait for RC1 to do this.

We are working on Init.ps1 support... but I don't have an exact time that it will light up (before RTM, but I'm not exactly sure what release).

ToddThomson commented 8 years ago

@rowanmiller Good decision. I can now move to Identity 3 and what I can to EF7 and wait for TPT/TPC. Thank-you for the update!

ghrapan commented 8 years ago

Hi guys!

In case somebody is looking for an example of how to make Identity 3.0 to utilize EF6 instead of EF7, I have published my implementation here:

https://github.com/entrypointsoft/AspNet.Identity.EntityFramework6

SharePointRadi commented 8 years ago

Another sample here: https://github.com/OneBitSoftware/Microsoft.AspNet.Identity.EntityFramework6

mrahhal commented 8 years ago

For anybody looking for a dnx based EF6 migrator, I've implemented one here: Migrator.EF6.