7

tl;dr: Identity seems to require that LazyLoading NOT be disabled; is this true, and what is the cleanest workaround?

I did some basic A-B testing on a simple C# ASP.NET 4.5.1 MVC-5 web application using EntityFramework 6.0.2, Identity EntityFramework 1.0.0, and Identity Owin 1.0.0 and it appears that Owin requires that lazy loading is NOT disabled in the ApplicationContext constructor.

To replicate the issue just make a quick MVC app using Visual Studio 2013, use the MVC template, leave everything at the defaults except uncomment the line: 'app.UseGoogleAuthentication();' in App_Start/Startup.Auth.cs. Run the app and use Google to login, complete the abbreviated registration page it takes you to and go to account/manage. You should see 2 buttons for Google at the bottom. Stop the app.

Now go to ApplicationContext.cs and change the constructor as shown in this code snippet:

public ApplicationContext() : base("DefaultConnection") { } //Works!

public ApplicationContext() : base("DefaultConnection") 
{
    this.Configuration.LazyLoadingEnabled = false;
} //Does not work

Retry the test. Only 1 Google button should be visible. With LazyLoadingEnabled = false the User Roles, Logins (poss Claims also) aren't loaded.

My theory is that this is a Microsoft oversight/'future feature' as Identity EntityFramework and Identity Owin are both version 1.0.0.

My question is, can this test be confirmed, and what is the cleanest work around?

For my purposes I will just use .ToList() and other methods for forcing EagerLoading when I want to use it. I don't truly need LazyLoading disabled, it's just a safer way to code if you want to always use eager loading. i.e. you miss one spot, it makes it to production, and you have a nice bug where in some View you are iterating through a Model and for Model.x.y y == null and the database connection has been disposed.

Let's not get into Identity vs. other (more robust) methods, or:

using (DatabaseContext) { //Database query } 

or calling dispose on every method vs letting the connection be disposed automatically. This is a scenario where you have to use Identity Owin, and dispose of all database calls ASAP. There ought to be something I'm missing, or maybe Identity really is just that incomplete right now.

  • OWIN and Katana are not the same as ASP.NET Identity. I'd suggest building a console application that uses ASP.NET Identity to prove or disprove what you're getting at in this post. – Brock Allen Jan 01 '14 at 16:04

1 Answers1

14

Yes this was a bug we have fixed in the 2.0.0-alpha1 release. With lazyLoading explicitly disabled prior, EF would not load the associated user entities automatically (logins/claims/roles)

Hao Kung
  • 28,040
  • 6
  • 84
  • 93
  • Interesting whether or not such sincere confession should be upvoted or downvoted because of the bug... I will upvote. – Wiktor Zychla Jan 02 '14 at 19:19
  • This is exactly what I was looking for and now I know after which release I can try removing my work-around. This also explains why [Authorize(Roles = "Admin")] wasn't working. Quite the frustrating bug. Although I could see how it would be missed, forcing eager loading usually is avoided for performance issues. For my particular app the Db Model is so simple that it should have no noticeable difference and will allow me to close connections the instant my queries finish. – David O'Brien Jan 05 '14 at 12:18
  • @Hao Kung could this be the same problem I am having with this other issue: https://stackoverflow.com/questions/24214840/cannot-login-on-asp-net-identity-2-site-after-programmatic-user-creation ? – Lord of Scripts Jun 16 '14 at 18:26
  • What about when wanting to get *all* users and aggregate their claims? – George Mauer Sep 23 '15 at 20:45