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

asp.net-identity dbcontext ef-code-first entity-framework

Question

My app is an MVC 5 one. I want to use the default aspnet.identity provider to make it possible for users to log in through the default "Account views." But I also need to connect to a different database, and I want to do so by using EF code-first.

I borrowed the context from a Scott Allen Pluralsight to use in my main database. I have no idea why the "ApplicationUser" class is deriving from the IdentityUser, but it worked with a previous website I developed and in his video. It looks like this:

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 third-party database is situated in the following context:

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; }
    }
}

I can successfully get data from the third-party website when I run the website. However, I get the following notice when I attempt to log in:

Invalid column name 'Discriminator'

As a result of placing the call, this gets thrown:

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

activating EF Profiler It appears to be trying to run 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]

The AspNetUsersTable has no discriminator column, which is a problem.

Could someone kindly clarify where I went wrong and how to fix it?

1
2
10/19/2014 12:40:33 PM

Accepted Answer

I started from scratch and made a fresh MVC 5 application before doing a database migration by executing the commands shown below from the package management console:

  • enable-migrations
  • first-add migration

When I looked at the resulting code, I could see that the AspNetUsers table contained a "Discriminator" field. After comparing the "initial" migration code from my separate DataAccess project, I went back to my "actual" solution. The "Discriminator" column was missing from this code, but I also observed that it had other fields like "PhoneNumber" and "TwoFactorEnabled." It came out that the MVC5 template was using an older version of "Microsoft.AspNet.Identity.EntityFramework" because of this.

In order to fix that, I went to the MVC5 web app's Control the Nuget packages dialog, deleted "Microsoft.AspNet.Identity.EntityFramework," then reinstalled it (v2.0). After that, everything worked perfectly when I logged in via the website as it didn't attempt to locate a "discriminator" column.

I believe I've learned from this to pay closer attention to the versions of Nuget packages that VS Templates utilize.

7
10/19/2014 4:15:10 PM

Popular Answer

The "ApplicationUser" class in the ASP.NET MVC project already overrides IdentityUser, so it automatically adds the Discriminator column to the entity framework for you. Try deleting the database and restarting.

Verify this: zzzz-9 zzzz



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow