EF 6 - Invalid column name 'Discriminator', two DbContexts

13,454

Solution 1

I went back to basics, created a new MVC 5 app then generated a db migrations by running the following from the package manager console:

  • enable-migrations
  • add-migration 'first

When I inspected the code that was generated I could see that it included a "Discriminator" column in the AspNetUsers table. I went back to my "real" solution and compared, the 'first' migration code from my separate DataAccess project. This code didn't have a "Discriminator" column, I also noticed that it had additional columns such as "PhoneNumber" and "TwoFactorEnabled". This made me think that perhaps the MVC5 template was using a previous version of "Microsoft.AspNet.Identity.EntityFramework" - this turned out the be the case.

To resolve I went to the Manage Nuget Packages dialog of the MVC5 web app, uninstalled "Microsoft.AspNet.Identity.EntityFramework"(v1.0) then re-installed (v2.0). Subsequently when I ran login from the website it no tried to find a "discriminator" column and everything worked great.

I guess this has taught me a valuable lesson to pay more attention to the versions on Nuget packages that are used by VS Templates

Solution 2

because the ASP.NET MVC project has a "ApplicationUser" class that already overrides IdentityUser it adds the Discriminator column to the entity framework for you automatically. Try to drop the data base and rerun. again.

Check this http://forums.asp.net/t/1970682.aspx?ASP+NET+Identity+V2+Discriminator+Column

Share:
13,454
Rob Bowman
Author by

Rob Bowman

Updated on June 05, 2022

Comments

  • Rob Bowman
    Rob Bowman over 1 year

    I have an MVC 5 app. I would like to use the standard aspnet.identity provider to enable user login through the standard \Account views. However, I also need to connect to a third-party database and want to use EF code-first for this too.

    The context for my main database I took from a Scott Allen Pluralsight. I don't know why or what the "ApplicationUser" class is doing inheriting from the IdentityUser but it worked in his video and with a previous website I created. It looks as follows:

    namespace ESBAMPortal.DataLayer
    {
        // You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more.
        public class ApplicationUser : IdentityUser
        {
        }
    
        class PortalContext : IdentityDbContext<ApplicationUser>, ESBAMPortal.DataLayer.IPortalContext
        {
            public PortalContext()
                : base("ESBamPortalConString")
            {
                this.Configuration.LazyLoadingEnabled = false;
            }
    
            public virtual DbSet<DomainClasses.Portal> Portal {get; set;}
        }
    }
    

    The context for the third-party database is as follows:

    namespace ESBAMPortal.DataLayer
    {
    
        public class ESBContext : DbContext, ESBAMPortal.DataLayer.IESBContext
        {
            public ESBContext()
                : base("ESBExceptionConString")
            {
                this.Configuration.LazyLoadingEnabled = false;
            }
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
            }
    
            public virtual DbSet<ActionType> ActionTypes { get; set; }
            public virtual DbSet<Alert> Alerts { get; set; }
            public virtual DbSet<AlertCondition> AlertConditions { get; set; }
            public virtual DbSet<AlertEmail> AlertEmails { get; set; }
            public virtual DbSet<AlertHistory> AlertHistories { get; set; }
            public virtual DbSet<AlertSubscription> AlertSubscriptions { get; set; }
            public virtual DbSet<AlertSubscriptionHistory> AlertSubscriptionHistories { get; set; }
            public virtual DbSet<AuditLog> AuditLogs { get; set; }
            public virtual DbSet<AuditLogMessageData> AuditLogMessageDatas { get; set; }
            public virtual DbSet<Batch> Batches { get; set; }
            public virtual DbSet<Configuration> Configurations { get; set; }
            public virtual DbSet<ContextProperty> ContextProperties { get; set; }
            public virtual DbSet<Fault> Faults { get; set; }
            public virtual DbSet<Message> Messages { get; set; }
            public virtual DbSet<MessageData> MessageDatas { get; set; }
            public virtual DbSet<ProcessedFault> ProcessedFaults { get; set; }
            public virtual DbSet<UserSetting> UserSettings { get; set; }
        }
    }
    

    When I run the website I am able to pull data from the third-party website ok. However, when I try to login I receive the message:

    Invalid column name 'Discriminator'
    

    This is thrown as a result of making the call:

    var user = await UserManager.FindAsync(model.UserName, model.Password);
    

    Running EF Profiler I can see that it's attempting to execute the following SQL:

    SELECT [Limit1].[C1]            AS [C1],
           [Limit1].[Id]            AS [Id],
           [Limit1].[UserName]      AS [UserName],
           [Limit1].[PasswordHash]  AS [PasswordHash],
           [Limit1].[SecurityStamp] AS [SecurityStamp]
    FROM   (SELECT TOP (1) [Extent1].[Id]            AS [Id],
                           [Extent1].[UserName]      AS [UserName],
                           [Extent1].[PasswordHash]  AS [PasswordHash],
                           [Extent1].[SecurityStamp] AS [SecurityStamp],
                           '0X0X'                    AS [C1]
            FROM   [dbo].[AspNetUsers] AS [Extent1]
            WHERE  ([Extent1].[Discriminator] = N'ApplicationUser')
                   AND ((((UPPER([Extent1].[UserName])) = (UPPER('rob' /* @p__linq__0 */)))
                         AND (NOT ((UPPER([Extent1].[UserName]) IS NULL)
                                    OR (UPPER('rob' /* @p__linq__0 */) IS NULL))))
                         OR ((UPPER([Extent1].[UserName]) IS NULL)
                             AND (UPPER('rob' /* @p__linq__0 */) IS NULL)))) AS [Limit1]
    

    Problem is, the AspNetUsersTable has no discriminator column.

    Could anyone please explain where I've gone wrong and how I should fix?

  • Ben Junior
    Ben Junior over 8 years
    I used the accepted solution above but I voted up yours cause it also works.
  • GianT971
    GianT971 over 7 years
    I have the same problem when trying to register a user, at the line userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);, and I am using latest stable version 2.2.1
  • JP Tétreault
    JP Tétreault almost 7 years
    based on your answer, I did the following and it fixed the issue by updating to the latest version : Install-Package Microsoft.AspNet.Identity.EntityFramework