Question

I am completely new to using code first for modeling databases. I've tried to follow several different tutorials and run into issues with all of them, and cannot ever figure out why.

Right now I have a new MVC 4 project. I'm working on this project with 3 others, and we are using Team Foundation Server for source control. Following various tutorials, I've set up my models as so:

public class User
{
    public int UserId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }

    public virtual ICollection<Entry> Entries { get; set; }
    public virtual ICollection<Rating> Ratings { get; set; }
}

public class Contest
{
    public int ContestId { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public DateTime Start { get; set; }
    public DateTime End { get; set; }
    public Boolean Published { get; set; }

    public virtual ICollection<Submission> Submissions { get; set; }
    public virtual ICollection<Tab> Tabs { get; set; }
}

public class Tab
{
    public int TabId { get; set; }
    public string Name { get; set; }
    public int Order { get; set; }
    public string Content { get; set; }
    public int ContestId { get; set; }

public virtual Contest Contest { get; set; }
}

public class Entry
{
    public int EntryId { get; set; }
    public string Title { get; set; }
    public string EmbedURL { get; set; }
    public string Description { get; set; }
    public Boolean isApproved { get; set; }
    public int UserId { get; set; }

    public virtual ICollection<Submission> Submissions { get; set; }

    public virtual User User { get; set; }
}

public class Submission
{
    public int SubmissionId { get; set; }
    public DateTime Submitted { get; set; }
    public int EntryId { get; set; }
    public int ContestId { get; set; }

    public virtual Entry Entry { get; set; }
    public virtual Contest Contest { get; set; }
}

public class Rating
{
    public int RatingId { get; set; }
    public int Stars { get; set; }
    public int UserId { get; set; }
    public int SubmissionId { get; set; }


    public virtual User User { get; set; }
    public virtual Submission Submission { get; set; }
}

and created an extension of DbContext:

public class CPContext : DbContext
{
    public CPContext() : base("name=CPContext")
    {
    }

    public DbSet<Contest> Contests { get; set; }
    public DbSet<User> Users { get; set; }
    public DbSet<Entry> Entries { get; set; }
    public DbSet<Submission> Submissions { get; set; }
    public DbSet<Rating> Ratings { get; set; }
    public DbSet<Tab> Tabs { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
    }
}

Finally, the connection string in my Web.config file:

<add name="CPContext" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=aspnet_ContestPlatform;Integrated Security=True;MultipleActiveResultSets=True" providerName="System.Data.SqlClient" />

In addition to all this, I'm initializing my database with the test data below:

//Will seed the database with dummy values when accessed for first time
public class ContestPlatformInitializer : DropCreateDatabaseIfModelChanges<CPContext>
{
    protected override void Seed(CPContext context)
    {
        var users = new List<User>
        {
            new User { FirstName = "Daniel", LastName = "Hines", Email = "hinesd@blah.edu" },
            new User { FirstName = "Peter", LastName = "Pan", Email = "panp@blah.edu" },
            new User { FirstName = "Marie", LastName = "VerMurlen", Email = "vermurle@blah.edu" },
            new User { FirstName = "Aaron", LastName = "Brown", Email = "browna5@blah.edu" }
        };
        users.ForEach(s => context.Users.Add(s));
        context.SaveChanges();

        var entries = new List<Entry>
        {
            new Entry { UserId = 1, Title = "Flight Simulation", EmbedURL = "www.blah.com/video1", Description = "This is an awesome app!", isApproved = true },
            new Entry { UserId = 2, Title = "Underwater Explorer", EmbedURL = "www.blah.com/video1", Description = "This is an awesome app!!", isApproved = true },
            new Entry { UserId = 3, Title = "Dress-Up", EmbedURL = "www.blah.com/video1", Description = "This is an awesome app!!!", isApproved = true },
            new Entry { UserId = 4, Title = "Combat Training", EmbedURL = "www.blah.com/video1", Description = "This is an awesome app!!!!", isApproved = true },
            new Entry { UserId = 1, Title = "Fitness Pro", EmbedURL = "www.blah.com/video1", Description = "This is an awesome app!!!!!", isApproved = true }
        };
        entries.ForEach(s => context.Entries.Add(s));
        context.SaveChanges();

        var contests = new List<Contest>
        {
            new Contest { Name = "Game Contest", Description = "This contest is to see who can make the most awesome game!", Start = DateTime.Parse("2012-02-10"), End = DateTime.Parse("2012-04-20"), Published = true },
            new Contest { Name = "App Contest", Description = "This contest is to see who can make the coolest app!", Start = DateTime.Parse("2012-03-10"), End = DateTime.Parse("2012-09-20"), Published = false }
        };
        contests.ForEach(s => context.Contests.Add(s));
        context.SaveChanges();

        var tabs = new List<Tab>
        {
            new Tab { ContestId = 1, Name = "Rules", Content = "The first rule is that there are no rules!", Order = 1 },
            new Tab { ContestId = 2, Name = "Examples", Content = "No examples here yet, check back soon.", Order = 1}
        };
        tabs.ForEach(s => context.Tabs.Add(s));
        context.SaveChanges();

        var submissions = new List<Submission>
        {
            new Submission { ContestId = 1, EntryId = 1, Submitted = DateTime.Parse("2-13-2012") },
            new Submission { ContestId = 1, EntryId = 2, Submitted = DateTime.Parse("2-14-2012") },
            new Submission { ContestId = 1, EntryId = 3, Submitted = DateTime.Parse("2-15-2012") },
            new Submission { ContestId = 1, EntryId = 4, Submitted = DateTime.Parse("2-16-2012") },
        };
        submissions.ForEach(s => context.Submissions.Add(s));
        context.SaveChanges();

        var ratings = new List<Rating>
        {
            new Rating { Stars = 4, UserId = 1, SubmissionId = 1 },
            new Rating { Stars = 5, UserId = 2, SubmissionId = 1 },
            new Rating { Stars = 2, UserId = 3, SubmissionId = 1 },
            new Rating { Stars = 4, UserId = 4, SubmissionId = 1 },

            new Rating { Stars = 1, UserId = 1, SubmissionId = 2 },
            new Rating { Stars = 2, UserId = 2, SubmissionId = 2 },
            new Rating { Stars = 1, UserId = 3, SubmissionId = 2 },
            new Rating { Stars = 3, UserId = 4, SubmissionId = 2 },

            new Rating { Stars = 5, UserId = 1, SubmissionId = 3 },
            new Rating { Stars = 5, UserId = 2, SubmissionId = 3 },
            new Rating { Stars = 4, UserId = 3, SubmissionId = 3 }
        };
        ratings.ForEach(s => context.Ratings.Add(s));
        context.SaveChanges();
    }
}

which is called in my Application_Start() method in my Global.asax file.

So now to test that everything is working correctly, I created a controller for my Contest model, which generated a corresponding view. When I compile my application and try to call the Contest controller, an exception is thrown.

System.Data.EntityCommandExecutionException was unhandled by user code Message=An error occurred while executing the command definition. See the inner exception for details. Source=System.Data.Entity StackTrace: at System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior) at System.Data.Objects.Internal.ObjectQueryExecutionPlan.Execute[TResultType](ObjectContext context, ObjectParameterCollection parameterValues) at System.Data.Objects.ObjectQuery1.GetResults(Nullable1 forMergeOption) at System.Data.Objects.ObjectQuery1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() at System.Collections.Generic.List1..ctor(IEnumerable1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source) at ContestPlatform.Controllers.ContestController.Index() in C:\Users\Danny\Documents\Visual Studio 2010\Projects\ContestPlatform\ContestPlatform\ContestPlatform\Controllers\ContestController.cs:line 21 at lambda_method(Closure , ControllerBase , Object[] ) at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c_DisplayClass42.b_41() at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c_DisplayClass37.<>c_DisplayClass39.b_33() at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c_DisplayClass4f.b__49() InnerException: System.Data.SqlClient.SqlException Message=Invalid object name 'dbo.Contest'. Source=.Net SqlClient Data Provider ErrorCode=-2146232060 Class=16 LineNumber=1 Number=208 Procedure="" Server=.\SQLEXPRESS State=1 StackTrace: at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) at System.Data.SqlClient.SqlDataReader.ConsumeMetaData() at System.Data.SqlClient.SqlDataReader.get_MetaData() at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) at System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior) InnerException:

Noticing the line "Message=Invalid object name 'dbo.Contest'", I wanted to double check that the table dbo.Contest was actually being generated.

I can go into Management Studio Express and see the database "aspnet_ContestPlatform", but it has no tables.

Is this the database I should be seeing? Why are no tables being generated? Also if the tables aren't there, why am I not getting an exception right when the application starts when the database is supposed to be getting seeded with the test data?

Was it helpful?

Solution

No, the name of the database should be [YourNamespace, if any].CPContext, not "aspnet_ContestPlatform".

I think the reason you're not getting an immediate exception is because it's only when you hit the view that uses the controller that actually executes your GetResults against the database that it falls over. Something is preventing the database from being created - not sure what - but as long as you don't select from it, nothing fails within the app.

Have you tried modifying the model, and running the app again? I often keep a dummy property on one of my minor entities that I alternately comment on/off to regenerate the database. I know it's not the best way to do things, but the model changes, and so the database should drop and recreate.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top