3

I've been staring at this for the last 5 hours, trying a bunch of things, but I'm not getting anywhere...

When I try to start my MVC website who's database I've created using Entity Framework Code First, the database fails to initialize, throwing the following exception message:

Sequence contains no matching elements

The first line of the stack trace below executes a Linq .Single query so I'm under the impression that it was looking for a single item in my model which doesn't exist. If this is correct, how do I find out what that item is?

Additionally, having reached my wits-end and thus deciding to go through absolutely all debugging information after the exception is thrown, I noticed the following in my Autos window:

Error message from Autos window

This is in direct reference to my OnModelCreating override:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Configurations.Add(new CompanyDBConfiguration());
        modelBuilder.Configurations.Add(new ClientDBConfiguration());
        modelBuilder.Configurations.Add(new QuoteDBConfiguration());
        modelBuilder.Configurations.Add(new RoleDBConfiguration());
        modelBuilder.Configurations.Add(new UserDBConfiguration());
        modelBuilder.Configurations.Add(new InvoiceDBConfiguration());
        modelBuilder.Configurations.Add(new JobDBConfiguration());
        modelBuilder.Configurations.Add(new JobStatusDBConfiguration());            
    }

Any information that can be used to get me closer to a solution will be greatly appreciated.

I'm sorry if there isn't enough information here, I'm at a loss at what to provide. Here's the stack trace though: (scroll down for edits)

System.InvalidOperationException was unhandled by user code
HResult=-2146233079
Message=Sequence contains no matching element
Source=System.Core
StackTrace:
at System.Linq.Enumerable.Single[TSource](IEnumerable1 source, Func2 predicate)
at System.Data.Entity.Utilities.DbProviderManifestExtensions.GetStoreTypeFromName(DbProviderManifest providerManifest, String name)
at System.Data.Entity.ModelConfiguration.Configuration.Properties.Primitive.PrimitivePropertyConfiguration.Configure(EdmProperty column, EntityType table, DbProviderManifest providerManifest, Boolean allowOverride, Boolean fillFromExistingConfiguration)
at System.Data.Entity.ModelConfiguration.Configuration.Properties.Primitive.PrimitivePropertyConfiguration.<>c__DisplayClass1.b__0(Tuple2 pm) at System.Data.Entity.Utilities.IEnumerableExtensions.Each[T](IEnumerable1 ts, Action1 action)
at System.Data.Entity.ModelConfiguration.Configuration.Properties.Primitive.PrimitivePropertyConfiguration.Configure(IEnumerable
1 propertyMappings, DbProviderManifest providerManifest, Boolean allowOverride, Boolean fillFromExistingConfiguration)
at System.Data.Entity.ModelConfiguration.Configuration.Types.StructuralTypeConfiguration.ConfigurePropertyMappings(IList1 propertyMappings, DbProviderManifest providerManifest, Boolean allowOverride)
at System.Data.Entity.ModelConfiguration.Configuration.Types.EntityTypeConfiguration.ConfigurePropertyMappings(DbDatabaseMapping databaseMapping, EntityType entityType, DbProviderManifest providerManifest, Boolean allowOverride)
at System.Data.Entity.ModelConfiguration.Configuration.Types.EntityTypeConfiguration.Configure(EntityType entityType, DbDatabaseMapping databaseMapping, DbProviderManifest providerManifest)
at System.Data.Entity.ModelConfiguration.Configuration.ModelConfiguration.ConfigureEntityTypes(DbDatabaseMapping databaseMapping, DbProviderManifest providerManifest)
at System.Data.Entity.ModelConfiguration.Configuration.ModelConfiguration.Configure(DbDatabaseMapping databaseMapping, DbProviderManifest providerManifest)
at System.Data.Entity.DbModelBuilder.Build(DbProviderManifest providerManifest, DbProviderInfo providerInfo)
at System.Data.Entity.DbModelBuilder.Build(DbConnection providerConnection)
at System.Data.Entity.Internal.LazyInternalContext.CreateModel(LazyInternalContext internalContext)
at System.Data.Entity.Internal.RetryLazy
2.GetValue(TInput input)
at System.Data.Entity.Internal.LazyInternalContext.InitializeContext()
at System.Data.Entity.Internal.LazyInternalContext.MarkDatabaseInitialized()
at System.Data.Entity.Database.Initialize(Boolean force)
at Jobber.Web.MvcApplication.Application_Start() in e:\Development\Jobber\Jobber.Web\Global.asax.cs:line 28
InnerException:

EDIT 1

Here's the code for Global.asax

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);

        WebDBContext db = new WebDBContext();
        db.Database.Initialize(true);
        db.Seed();
    }
}

And here's WebDBContext()

// BaseDBContext is a generic class that inherits from DbContext, see it's code below
public class WebDBContext : BaseDBContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Configurations.Add(new CompanyDBContext());
        modelBuilder.Configurations.Add(new ClientDBContext());
        modelBuilder.Configurations.Add(new QuoteDBContext());
        modelBuilder.Configurations.Add(new RoleDBContext());
        modelBuilder.Configurations.Add(new UserDBContext());
        modelBuilder.Configurations.Add(new InvoiceDBContext());
        modelBuilder.Configurations.Add(new JobDBContext());
        modelBuilder.Configurations.Add(new JobStatusDBContext());            
    }

    public WebDBContext()
    {
        Database.SetInitializer<WebDBContext>(new DropCreateDatabaseAlways<WebDBContext>());
    }

    public void Seed()
    {
        // seeds initial data into the database
    }

    public DbSet<User> Users { get; set; }
    public DbSet<Role> Roles { get; set; }
    public DbSet<Client> Clients { get; set; }
    public DbSet<Company> Companies { get; set; }
    public DbSet<Invoice> Invoices { get; set; }
    public DbSet<Job> Jobs { get; set; }
    public DbSet<JobStatus> JobStatuses { get; set; }
    public DbSet<Quote> Quotes { get; set; }

BaseDBContext:
This class just provides a generic context that is not specific to any application. This allows for CRUD functionality to be written for objects which may be common between projects

public class BaseDBContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Configurations.Add(new BaseUserDBContext());
    }

    public BaseDBContext()
        : base()
    {
        Database.SetInitializer<BaseDBContext>(new DropCreateDatabaseIfModelChanges<BaseDBContext>());
    }

    public DbSet<BaseUser> Users { get; set; }
}

EDIT 2
Chris requested the ConnectionString and My UserDBContext (more about this below - VERY IMPORTANT STUFF)

  <connectionStrings>
    <add name="DefaultConnection" providerName="System.Data.SqlClient" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-Jobber.Web-20150105094927;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-Jobber.Web-20150105094927.mdf" />
  </connectionStrings>

public class UserDBContext : DBBaseObject<User>
{
    // application-specific columns
    public UserDBContext()
        : base()
    {
        //HasOptional(r => r.Role)
        //    .WithMany(m => m.Users)
        //   .Map(x => x.MapKey("fkRoleID"))
        //    .WillCascadeOnDelete(false);

        ToTable("Users");
    }
}

To start explaining this... I'm developing an application framework that handles all "globally common" structures and methods which is to say that it handles all things that can logically be assumed to be common between applications.

Things like a user object that contains a username and password for example.

The framework is put together with a lot of inheritance, abstract classes and some use of generics. Here's more or less what it looks like without all that:

Framework:

Logan.Base
{
    Logan.Base.BaseObject  
    - defines common fields that all tables will always have (PK, auditing, etc)  

    Logan.Base.BaseUser  
    - defines common fields that user tables will have (username, password, etc)
}  
Logan.DBBase  
{
    Logan.DBBase.BaseUserDBContext  
    - defines C#->SQL data type mappings for the BaseUser along with CRUD functions  

    Logan.DBBase.DBBaseObject  
    - defines C#->SQL data type mappings for columns that all tables will always have  

    Logan.DBBase.DBContext  
    - defines a DbContext to be used in the DBBaseObject
}

Logan.Base

namespace Logan.Base
{
    public abstract class BaseObject
    {
        public Int64 PKey { get; set; }
        public Int64 CreatedBy { get; set; }
        public DateTime CreatedOn { get; set; }
        public Int64 ModifiedBy { get; set; }
        public DateTime ModifiedOn { get; set; }

        public BaseObject()
        {
            PKey = 0;
            CreatedBy = 0;
            ModifiedBy = 0;
        }
    }

    public abstract class BaseUser : BaseObject
    {
        public string EmailAddress { get; set; }
        public string Password { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }

        public BaseUser()
        {
            EmailAddress = String.Empty;
            Password = String.Empty;
            FirstName = String.Empty;
            LastName = String.Empty;
        }        
    }
}

Logan.DBBase

namespace Logan.DBBase
{

    public abstract class DBBaseObject<T> : EntityTypeConfiguration<T>
        where T : BaseObject
    {

        public DBBaseObject()
            : base()
        {
            HasKey(p => p.PKey);
        }
    }

    public class BaseUserDBContext : DBBaseObject<BaseUser>
    {

        // common columns
        public BaseUserDBContext()
            : base()
        {
            Property(p => p.EmailAddress)
                .HasColumnName("sEmailAddress")
                .HasMaxLength(200)
                .IsRequired();

            Property(p => p.Password)
                .HasColumnName("sPassword")
                .HasMaxLength(255)
                .IsRequired();

            Property(p => p.FirstName)
                .HasColumnName("sFirstName")
                .IsRequired();

            Property(p => p.LastName)
                .HasColumnName("sLastName")
                .IsRequired();

            ToTable("Users");
        }

        // User CRUD functions that use the below DbContext go here
    }

    public class BaseDBContext : DbContext
    {
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            modelBuilder.Configurations.Add(new BaseUserDBContext());
        }

        public BaseDBContext()
            : base()
        {
            Database.SetInitializer<BaseDBContext>(new DropCreateDatabaseIfModelChanges<BaseDBContext>());
        }

        public DbSet<BaseUser> Users { get; set; }
    }
}
Ortund
  • 8,095
  • 18
  • 71
  • 139
  • Well, knowing what is at e:\Development\Jobber\Jobber.Web\Global.asax.cs:line 28 and it's surrounding code might help... – simon at rcl Jan 23 '15 at 14:53
  • @simonatrcl sure enough I can post the Global.asax code... what else do you need? – Ortund Jan 23 '15 at 14:54
  • Probably need to see your context initialiser too. – DavidG Jan 23 '15 at 14:55
  • Just post the method that line is in. We'll see after that. (Edit the question to add the code, don't put it as a comment - that becomes unreadable). – simon at rcl Jan 23 '15 at 14:55
  • @simonatrcl its all there now – Ortund Jan 23 '15 at 14:59
  • Put a break on the first line of the Application_Start method, and then run it,. Step through the code and see where it's going wrong. – simon at rcl Jan 23 '15 at 15:01
  • @simonatrcl it goes wrong just after it's done the `OnModelCreating` and wants to get onto the constructor for WebDBContext – Ortund Jan 23 '15 at 15:04
  • OK. I see from your stack trace that there is an Inner Exception which you haven't shown. Can you show that? And any other inner exceptions to that one. – simon at rcl Jan 23 '15 at 15:09
  • InnerException is null... This is a direct copy of all exception detail provided from VS – Ortund Jan 23 '15 at 15:12
  • Could you drop the database (take a backup first) and then let EF recreate it from scratch when you start your application? Curious to see if this resolves it. Also, why do you call Seed() if you don't seed the db with any data? – Chris Jan 23 '15 at 15:13
  • @Chris as of yet, EF hasn't been able to create any database due to this error – Ortund Jan 23 '15 at 15:14
  • Which EF version are you using? – Chris Jan 23 '15 at 15:24
  • @Chris EF dll says version 6.0.0.0 – Ortund Jan 23 '15 at 15:28
  • Remove and add the EF Nuget package. And could you attach the connection string pls? – Chris Jan 23 '15 at 15:37
  • You have an issue with `Single` and nowhere in this wall of code you show the line that throws the exception! – Gert Arnold Jan 23 '15 at 23:26
  • @GertArnold I never use .Single in any linq queries. The Single that's causing the issue, I believe, is within EF – Ortund Jan 24 '15 at 09:51
  • You shouldn't use a global context anyway. Not sure why the error occurs, but you should have a context per request. – Gert Arnold Jan 24 '15 at 10:33
  • 3
    I know this is old post and I hope that you have already solved your issue. But, in case not, have a look at this answer http://stackoverflow.com/a/26156805/1380428 – Adil Mammadov Feb 15 '16 at 08:32
  • 1
    @AdilMammadov, that's right! Who faced this strange error check your attributes, especially how length should be specified for nvarchar. Details in link. – StalkAlex Apr 22 '17 at 11:17

2 Answers2

3

For me the problem was I had a SQL_VARIANT type column in my table. Once I changed this to an nvarchar the error went away.

pmcilreavy
  • 3,076
  • 2
  • 28
  • 37
0

I think your DBContext has a couple of issues. I would go back to basics and once I got the DB initialization working I would then start adding things. So first of, drop the BaseDbContext and change you WebDBContext to this:

public class WebDBContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Configurations.Add(new CompanyDBContext());
        modelBuilder.Configurations.Add(new ClientDBContext());
        modelBuilder.Configurations.Add(new QuoteDBContext());
        modelBuilder.Configurations.Add(new RoleDBContext());
        modelBuilder.Configurations.Add(new UserDBContext());
        modelBuilder.Configurations.Add(new InvoiceDBContext());
        modelBuilder.Configurations.Add(new JobDBContext());
        modelBuilder.Configurations.Add(new JobStatusDBContext());            
    }

    public DbSet<User> Users { get; set; }
    public DbSet<Role> Roles { get; set; }
    public DbSet<Client> Clients { get; set; }
    public DbSet<Company> Companies { get; set; }
    public DbSet<Invoice> Invoices { get; set; }
    public DbSet<Job> Jobs { get; set; }
    public DbSet<JobStatus> JobStatuses { get; set; }
    public DbSet<Quote> Quotes { get; set; }
}  

Baby steps. Get this to work and then we can add the rest of the configuration, if it's still necessary

Chris
  • 5,040
  • 3
  • 20
  • 24
  • Okay I commented out everything except what you've shown here and I already got rid of BaseDBContext in favor of DbContext and nothing has changed. Interestingly enough, having stepped through this before, this step doesn't alter code that is actually executed in any way – Ortund Jan 23 '15 at 15:36
  • Where is your UserDbContext? I didn't see this: modelBuilder.Configurations.Add(new UserDBContext()); – Chris Jan 23 '15 at 15:39
  • all have been added under Edit 2 – Ortund Jan 23 '15 at 16:08