Skip to content
This repository has been archived by the owner on Dec 20, 2018. It is now read-only.

EF6 support… somehow? #416

Closed
cherrydev opened this issue Mar 20, 2015 · 18 comments
Closed

EF6 support… somehow? #416

cherrydev opened this issue Mar 20, 2015 · 18 comments
Milestone

Comments

@cherrydev
Copy link

I've come to realize over the last few months of working with it that EF7, while a spectacular and welcome break from the older versions, is not going to be ready for many types of serious production work by the time that the rest of ASPNET5 is release-quality. The team has made it pretty clear that the 1.0 release of EF7 will be missing a lot of functionality.
This has me in a bit of a bind with regards to the Identity framework, because as far as I've been able to tell, it's really the only portion of ASPNET5 that, effectively, is tightly bound to EF7, or at least not compatible with EF6.
Tightly bound, you ask? The EF7-specific portions of it are in a completely separate assembly, right? Yes, this is true. The problem with this is absolutely not the fault of the Identity framework, but with EF6:
It is impossible to create or use EF6 migrations within an ASPNET5-style project. For most cases, there's a work-around for this: you create your create a "classic" style project that contains your DbContext, create and use your migrations on that, and then use the "kpm wrap" command to create a project wrapper that can be referenced from aspnet5 projects.
So, what's the problem, then?
Well, "classic" style projects can't reference the Microsoft.AspNet.Identity package because it relies on the aspnet5 or aspnet5core runtime. Therefore it's not possible to create a DbContext that references IdentityUser, IdentityRole, etc, etc.
I can see that IdentityUser et all are really just utility classes and aren't strictly necessary to an implementation of IUserStore, IUserRoleStore, etc, etc, but it's also a huge waste to have to completely re-implement all the functionality those classes implement in order to build a functioning identity store in EF6.
So, one idea:
Move everything in the Identity assembly that has no external dependencies into a separate assembly that can be referenced from a classic .net project. This would make it very simple to implement an identity store in EF6.
Any ideas or thoughts about this? Has anyone successfully gotten this working with EF6 yet? Do you foresee any problems with creating another assembly containing the interfaces and POCOs that are useful in creating the Stores?

@cherrydev
Copy link
Author

Okay, I notice you've just done sorta the opposite of what I was requesting:
You moved all of the POCOs directly into the EntityFramework project instead of a 3rd project.
I guess this would make it slightly cleaner for me to make a direct port of Identity.EntityFramework to EF6 (since there would not be duplicate types in Identity) but doesn't really save any effort.

@cherrydev
Copy link
Author

Okay, so I managed to port the EF identity store provider to EF6 without too much trouble. The biggest problem was that EF6 doesn't support entities with type parameters, so this (ironically) meant adding a whole bunch more (mostly redundant) type parameters to IdentityDbContext, RoleStore, UserStore and everywhere that cascades to, which I believe is how the Identity 2 EF6 store is implemented too.
There's some commented out code in IdentityDbContext which actually seems to be redundant, below the builder definition for TUserRole:

            // Blocks delete currently without cascade
            //.ForeignKeys(fk => fk.ForeignKey<TUser>(f => f.UserId))
            //.ForeignKeys(fk => fk.ForeignKey<TRole>(f => f.RoleId));

But this is already declared above in the definitions of TRole and TUser and those FKs definitely already get generated.

Anyhow, what I've done is not very much work but on @Eilon 's advice, I'd like to contribute this back to the project (and I'm supposed to also mention @divega @rustd and @HaoK in this message!).

There's still another big issue, though, that I've also partially solved: If using the "kpm wrap" method of integrating an EF6 context into an aspnet5 project, an EF6 Identity.EntityFramework package can't be a single package that contains the POCOs, the DbContexts, UserStore & RoleStore and the builder extensions; the UserStore, RoleStore and builder extensions all depend on the core Identity package and therefore can't be referenced from .csproj style project. So, either this would need to be split into two different packages (a .csproj project and a aspnet5 project that depends on it) or we'd need an alternative to the "kpm wrap" method:

…which I have a working proof-of-concept of. I wrangled DbMigrator and Scaffolder in EF6 to work inside of a aspnet5 project in a similar manner to the "k ef" series of migration commands and it works cleanly without needing access to any internal or private classes or members.

So, this means that we now have a cross-project dependency in order to get this working, which seems a bit daunting to me. Is anyone willing to help me get this to happen? I suppose EF6 migration commands for aspnet5 would be its own new package, right?

@divega
Copy link

divega commented Apr 1, 2015

@cherrydev Thanks for the update, and great to hear you made all this progress.

Regarding the possibly redundant code in OnModelCreating() I believe we have a few workarounds in place for features that are still not implemented in the current EF7 bits but that should be there for RTM. @suhasj has been making updates to this model, so it would be good if we can take a look.

I actually would have expected you to have to split the packages between the "base data model" (i.e. base entity types and derived DbContext) and the stores. The application itself will also have to maintain a separate .csproj project with its data model if they want to use EF6 and be able to use migrations. They can put any customizations for the Identity data model in there too.

…which I have a working proof-of-concept of. I wrangled DbMigrator and Scaffolder in EF6 to work inside of a aspnet5 project in a similar manner to the "k ef" series of migration commands and it works cleanly without needing access to any internal or private classes or members

That sounds super interesting though. If it can be made to work without a lot of hacks we can consider it too.

cc @bricelam @rowanmiller

@cherrydev
Copy link
Author

As for the E6 migrations, it's not any sort of hack at all. It just uses the (public) DbMigrator and Scaffolder classes to create the .cs, Designer.cs and .resx files or update the database, which is what the PowerShell commands do. The only significant work to really do now is to get the command line processing and options sorted out.

@rustd rustd added this to the 3.0.0-beta5 milestone Apr 6, 2015
@rustd
Copy link

rustd commented May 18, 2015

@cherrydev anything we can help on this?

@rustd rustd modified the milestones: 3.0.0-beta5, 3.0.0-Beta6 May 18, 2015
@cherrydev
Copy link
Author

Thanks for the reminder. Now that I'm using the non-daily beta4 releases I should do some cleanup that fits better with this release. I'm a bit unsure where to go with the portion of the code for doing the EF6 migrations, since it's nothing specific for Identity, and it's not related to EF7. Basically, there doesn't seem to be a place for it in the aspnet github project umbrella. Any advice?

@divega
Copy link

divega commented May 18, 2015

cc @bricelam in case he has any insights on where to put the EF6 migrations command code. It wouldn't bother me if it was in the same repo as the EF6 provider for Identity at least at the start.

@ToddThomson
Copy link

👍 I would very much like to see this make the initial 3.0 release.

@ghrapan
Copy link

ghrapan commented Nov 30, 2015

I have created a direct port of Identity.EntityFramework namespace (RC1) to EF6:

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

Would somebody be interested to incorporate it?

@divega
Copy link

divega commented Dec 1, 2015

@ghrapan Thanks for the heads up. Have you considered a strategy to have automated test for this provider? Is there anything we can do, .e.g. refactoring our tests to enable reuse?

@cherrydev since you asked the same question first, are you still interested in contributing this? Did you ever get to implement automated tests for your provider?

@cherrydev
Copy link
Author

@divega It loos like what @ghrapan has is probably a bit further ahead than what I have, though what I have seems to work for my use cases so far. I think my private version uses a much earlier beta of AspNet.Identity.EntityFramework as a starting point and assuming that he's started with something much more recent, his implementation is probably more robust than mine is.
My sticking point for contribution right now is the fact that there is still no DNX support for EF6 commands officially available and while I'd be happy to contribute that work that I've been doing on that, I don't want to publish something that's either going to end up obsolete in a couple more months (if the existing EF6 PS commands somehow become usable with DNX), or stay responsible for maintaining it for the community without at least an endorsement from MS. The last I heard from you during the summer (here), it was still under discussion. I've poked you once since then but haven't gotten a response, so I've been waiting on some sort of word about what, if any, plans there are within MS for supporting EF6 commands on DNX.

@cherrydev
Copy link
Author

@divega Feel free to e-mail me at this username at gmail if you want to discuss it.

@divega
Copy link

divega commented Dec 1, 2015

@cherrydev Personally I am not sure that PowerShell commands and a DNX-like command line interface are full replacements for each other. And sorry I didn't come back to you on that thread but the truth is that many things are being discussed about the command line tools, e.g. dotnet/efcore#3925.

What about the automated test part?

@cherrydev
Copy link
Author

No, I have not specifically write automated tests for the EF provider for the Identity framework. I have, however, ported over a portion of the EF7 self-test utilities that automate the creation and destruction of databases for the purposes of tests. That might be a prerequisite to writing effective and efficient tests for a EF6 identity provider.

@SharePointRadi
Copy link

I have also created an EF6 library for Identity 3. Its quite important because EF7 is not that feature-complete.
You can take a look here:
https://github.com/OneBitSoftware/Microsoft.AspNet.Identity.EntityFramework6

All unit tests pass and I have included a sample MVC6 project so people can get started easily. I would love to put more work in and get it contributed.

@mrahhal
Copy link

mrahhal commented Mar 8, 2016

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

@HaoK
Copy link
Member

HaoK commented Nov 18, 2016

We are not planning on releasing our own EF6 provider, but we think this would be something valuable for the community to provide.

@HaoK HaoK closed this as completed Nov 18, 2016
@weitzhandler
Copy link

weitzhandler commented May 17, 2017

@HaoK
The problem is there are zillion of implementations with not a single one even recommended officially. You don't want to implement one yourself that's fine, please at lease recommend one officially.

Here's my single-file and small (<250 lines) ASP.NET Core IUserStore<TUser> wrapper around the ASP.NET Identity's UserStore<TUser, TKey>, would love to hear any comments.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

9 participants