MVC 5 with EF 6 in Visual Basic - Creating an Entity Framework Data Model

This tutorial is the first in a series of a Visual Basic versions of the Getting Started with EF 6 using MVC 5 tutorials published on the www.asp.net site. The original series, produced by Tom Dykstra and Rick Anderson ( @RickAndMSFT ) was written using the C# language. My versions keep as close to the originals as possible, changing only the coding language. The narrative text is largely unchanged from the original and is used with permission from Microsoft.

The tutorial series teaches you how to create ASP.NET MVC 5 applications using the Entity Framework 6 and Visual Studio 2013 Express for Web. This tutorial uses the Code First workflow. For information about how to choose between Code First, Database First, and Model First, see Entity Framework Development Workflows.

The tutorial series comprises 12 sections in total. They are intended to be followed sequentially as each section builds on the knowledge imparted in the previous sections. Progress through the sections is reflected in a Visual Studio Express for Web project download that accompanies each section which features the web application that you build through the series.

Download the code

The code for this section is available here. Save the .zip file to a convenient location and then extract the contents. Make sure you have an edition of Visual Studio 2013 installed (Express for Web, Professional, Premium or Ultimate) and double click the .sln file. Once the project is opened in your IDE, press Shift+Ctrl+B to build the solution. This will ensure that all packages are restored from Nuget and may take a while depending on your Internet connection speed.

The navigation path through the series is as follows:

  1. Creating an Entity Framework Data Model
  2. Implementing Basic CRUD Functionality
  3. Sorting, Filtering and Paging
  4. Connection Resiliency and Command Interception
  5. Code First Migrations and Deployment
  6. Creating a More Complex Data Model
  7. Reading Related Data
  8. Updating Related Data
  9. Async and Stored Procedures
  10. Handling Concurrency
  11. Implementing-Inheritance
  12. Advanced Entity Framework Scenarios

The Contoso University Web Application

The application you'll be building in these tutorials is a simple university web site.

Users can view and update student, course, and instructor information. Here are a few of the screens you'll create.

Contoso University

Contoso University

 

The UI style of this site has been kept close to what's generated by the built-in templates, so that the tutorial can focus mainly on how to use the Entity Framework.

Create an MVC Web Application

Open Visual Studio and create a new C# Web project named "ContosoUniversity".

Contoso University

In the New ASP.NET Project dialog box select the MVC template.

Click Change Authentication.

Contoso University

In the Change Authentication dialog box, select No Authentication, and then click OK. For this tutorial you won't be requiring users to log on or restricting access based on who's logged on.

Contoso University

Back in the New ASP.NET Project dialog box, click OK to create the project. 

Set Up the Site Style

A few simple changes will set up the site menu, layout, and home page.

Open Views\Shared\_Layout.vbhtml, and make the following changes:

  • Change each occurrence of "My ASP.NET Application" and "Application name" to "Contoso University".
  • Add menu entries for Students, Courses, Instructors, and Departments.

The changes are highlighted.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@ViewBag.Title - Contoso University</title>
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")
</head>
<body>
    <div class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                @Html.ActionLink("Contoso University", "Index", "Home", Nothing, New With {.class = "navbar-brand"})
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li>@Html.ActionLink("Home", "Index", "Home")</li>
                    <li>@Html.ActionLink("About", "About", "Home")</li>
                    <li>@Html.ActionLink("Students", "Index", "Student")</li>
                    <li>@Html.ActionLink("Courses", "Index", "Course")</li>
                    <li>@Html.ActionLink("Instructors", "Index", "Instructor")</li>
                    <li>@Html.ActionLink("Departments", "Index", "Department")</li>
               </ul>
            </div>
        </div>
    </div>
    <div class="container body-content">
        @RenderBody()
        <hr />
        <footer>
            <p>&copy; @DateTime.Now.Year - Contoso University</p>
        </footer>
    </div>

    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/bootstrap")
    @RenderSection("scripts", required:=False)
</body>
</html>

In Views\Home\Index.vbhtml, replace the contents of the file with the following code to replace the text about ASP.NET and MVC with text about this application:

@Code
    ViewBag.Title = "Home Page"
End Code

<div class="jumbotron">
    <h1>Contoso University</h1>
</div>
<div class="row">
    <div class="col-md-4">
        <h2>Welcome to Contoso University</h2>
        <p>
            Contoso University is a sample application that
            demonstrates how to use Entity Framework 6 in an
            ASP.NET MVC 5 web application with Visual Basic as the development language.
        </p>
    </div>
    <div class="col-md-4">
        <h2>Build it from scratch</h2>
        <p>You can build the application by following the steps in the tutorial series on the ASP.NET site.</p>
        <p><a class="btn btn-default" href="http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/">See the tutorial &raquo;</a></p>
    </div>
    <div class="col-md-4">
        <h2>Download it</h2>
        <p>You can download the completed project from the Mikesdotnetting.</p>
        <p><a class="btn btn-default" href="http://code.msdn.microsoft.com/ASPNET-MVC-Application-b01a9fe8">Download &raquo;</a></p>
    </div>
</div>

Press CTRL+F5 to run the site. You see the home page with the main menu.

MVC5 With EF6

Install Entity Framework 6

From the Tools menu click Library Package Manager and then click Package Manager Console.

In the Package Manager Console window enter the following command:

Install-Package EntityFramework

MVC5 With EF6 

 

The image shows 6.1.0 being installed, but NuGet will install the latest version of Entity Framework (excluding pre-release versions.

The next step is one of a few steps that this tutorial has you do manually, but which could have been done automatically by the ASP.NET MVC scaffolding feature. You're doing them manually so that you can see the steps required to use the Entity Framework. You'll use scaffolding later to create the MVC controller and views. An alternative is to let scaffolding automatically install the EF NuGet package, create the database context class, and create the connection string. When you're ready to do it that way, all you have to do is skip those steps and scaffold your MVC controller after you create your entity classes. 

Create the Data Model

Next you'll create entity classes for the Contoso University application. You'll start with the following three entities:

MVC5 With EF6 

There's a one-to-many relationship between Student and Enrollment entities, and there's a one-to-many relationship between Course and Enrollment entities. In other words, a student can be enrolled in any number of courses, and a course can have any number of students enrolled in it.

In the following sections you'll create a class for each one of these entities.

Note If you try to compile the project before you finish creating all of these entity classes, you'll get compiler errors.

The Student Entity

MVC5 With EF6 

In the Models folder, create a class file named Student.vb and replace the template code with the following code:

Namespace Models
    Public Class Student
        Public Property ID As Integer
        Public Property LastName As String
        Public Property FirstMidName As String
        Public Property EnrollmentDate As DateTime

        Public Overridable Property Enrollments As ICollection(Of Enrollment)
    End Class
End Namespace

The ID property will become the primary key column of the database table that corresponds to this class. By default, the Entity Framework interprets a property that's named ID or classnameID as the primary key.

The Enrollments property is a navigation property. Navigation properties hold other entities that are related to this entity. In this case, the Enrollments property of a Student entity will hold all of the Enrollment entities that are related to that Student entity. In other words, if a given Student row in the database has two related Enrollment rows (rows that contain that student's primary key value in their StudentID foreign key column), that Student entity's Enrollments navigation property will contain those two Enrollment entities.

Navigation properties are typically defined as virtual so that they can take advantage of certain Entity Framework functionality such as lazy loading. (Lazy loading will be explained later, in the Reading Related Data tutorial later in this series.)

If a navigation property can hold multiple entities (as in many-to-many or one-to-many relationships), its type must be a list in which entries can be added, deleted, and updated, such as ICollection.

The Enrollment Entity

MVC5 With EF6 

In the Models folder, create Enrollment.vb and replace the existing code with the following code:

Namespace Models
    Public Enum Grade
        A
        B
        C
        D
        E
        F
    End Enum

    Public Class Enrollment
        Public Property EnrollmentID As Integer
        Public Property CourseID As Integer
        Public Property StudentID As Integer
        Public Property Grade As Grade?

        Public Overridable Property Course As Course
        Public Overridable Property Student As Student
    End Class
End Namespace

The EnrollmentID property will be the primary key; this entity uses the classnameID pattern instead of ID by itself as you saw in the Student entity. Ordinarily you would choose one pattern and use it throughout your data model. Here, the variation illustrates that you can use either pattern. In a later tutorial, you'll see how using ID without classname makes it easier to implement inheritance in the data model.

The Grade property is an enum. The question mark after the Grade type declaration indicates that the Grade property is nullable. A grade that's null is different from a zero grade — null means a grade isn't known or hasn't been assigned yet.

The StudentID property is a foreign key, and the corresponding navigation property is Student. An Enrollment entity is associated with one Student entity, so the property can only hold a single Student entity (unlike the Student.Enrollments navigation property you saw earlier, which can hold multiple Enrollment entities).

The CourseID property is a foreign key, and the corresponding navigation property is Course. An Enrollment entity is associated with one Course entity.

Entity Framework interprets a property as a foreign key property if it's named <navigation property name><primary key property name> (for example, StudentID for the Student navigation property since the Student entity's primary key is ID). Foreign key properties can also be named the same simply <primary key property name> (for example, CourseID since the Course entity's primary key is CourseID).

The Course Entity

MVC5 With EF6

 

In the Models folder, create Course.vb, replacing the template code with the following code:

Imports System.ComponentModel.DataAnnotations.Schema
Namespace Models
    Public Class Course
        <DatabaseGenerated(DatabaseGeneratedOption.None)>
        Public Property CourseID As Integer
        Public Property Title As String
        Public Property Credits As Integer

        Public Overridable Property Enrollments As ICollection(Of Enrollment)
    End Class
End Namespace

The Enrollments property is a navigation property. A Course entity can be related to any number of Enrollment entities.

We'll say more about the DatabaseGenerated attribute in a later tutorial in this series. Basically, this attribute lets you enter the primary key for the course rather than having the database generate it.

Create the Database Context

The main class that coordinates Entity Framework functionality for a given data model is the database context class. You create this class by deriving from the System.Data.Entity.DbContext class. In your code you specify which entities are included in the data model. You can also customize certain Entity Framework behavior. In this project, the class is named SchoolContext.

To create a folder in the ContosoUniversity project, right-click the project in Solution Explorer and click Add, and then click New Folder. Name the new folder DAL (for Data Access Layer). In that folder create a new class file named SchoolContext.vb, and replace the template code with the following code:

Imports ContosoUniversity.Models
Imports System.Data.Entity
Imports System.Data.Entity.ModelConfiguration.Conventions
Namespace DAL
    Public Class SchoolContext
        Inherits DbContext

        Public Sub New()
            MyBase.New("SchoolContext")
        End Sub

        Public Property Students As DbSet(Of Student)
        Public Property Enrollments As DbSet(Of Enrollment)
        Public Property Courses As DbSet(Of Course)

        Protected Overrides Sub OnModelCreating(ByVal modelBuilder As DbModelBuilder)
            modelBuilder.Conventions.Remove(Of PluralizingTableNameConvention)()
        End Sub
    End Class
End Namespace

Specifying entity sets

This code creates a DbSet property for each entity set. In Entity Framework terminology, an entity set typically corresponds to a database table, and an entity corresponds to a row in the table.

You could have omitted the DbSet(Of Enrollment) and DbSet(Of Course) statements and it would work the same. The Entity Framework would include them implicitly because the Student entity references the Enrollment entity and the Enrollment entity references the Course entity.

Specifying the connection string

The name of the connection string (which you'll add to the Web.config file later) is passed in to the constructor.

 

Public Sub New()
            MyBase.New("SchoolContext")

You could also pass in the connection string itself instead of the name of one that is stored in the Web.config file. For more information about options for specifying the database to use, see Entity Framework - Connections and Models.

If you don't specify a connection string or the name of one explicitly, Entity Framework assumes that the connection string name is the same as the class name. The default connection string name in this example would then be SchoolContext, the same as what you're specifying explicitly.

Specifying singular table names

The modelBuilder.Conventions.Remove statement in the OnModelCreating method prevents table names from being pluralized. If you didn't do this, the generated tables in the database would be named StudentsCourses, and Enrollments. Instead, the table names will be StudentCourse, and Enrollment. Developers disagree about whether table names should be pluralized or not. The original tutorial uses the singular form so we will stick with that- although my personal preference is the plural form, but the important point is that you can select whichever form you prefer by including or omitting this line of code, and once haivng made that selection, you should be consistent.

Set up EF to initialize the database with test data

The Entity Framework can automatically create (or drop and re-create) a database for you when the application runs. You can specify that this should be done every time your application runs or only when the model is out of sync with the existing database. You can also write a Seed method that the Entity Framework automatically calls after creating the database in order to populate it with test data.

The default behavior is to create a database only if it doesn't exist (and throw an exception if the model has changed and the database already exists). In this section you'll specify that the database should be dropped and re-created whenever the model changes. Dropping the database causes the loss of all your data. This is generally OK during development, because the Seed method will run when the database is re-created and will re-create your test data. But in production you generally don't want to lose all your data every time you need to change the database schema. Later you'll see how to handle model changes by using Code First Migrations to change the database schema instead of dropping and re-creating the database.

In the DAL folder, create a new class file named SchoolInitializer.vb and replace the template code with the following code, which causes a database to be created when needed and loads test data into the new database.

Imports System.Collections.Generic
Imports System.Linq
Imports System.Web
Imports System.Data.Entity
Imports ContosoUniversity.Models

Namespace DAL
    Public Class SchoolInitializer
        Inherits DropCreateDatabaseIfModelChanges(Of SchoolContext)
        Protected Overrides Sub Seed(ByVal context As SchoolContext)
            Dim students = New List(Of Student)() From {
                New Student() With {
                    .FirstMidName = "Carson",
                    .LastName = "Alexander",
                    .EnrollmentDate = DateTime.Parse("2005-09-01")
                },
                New Student() With {
                    .FirstMidName = "Meredith",
                    .LastName = "Alonso",
                    .EnrollmentDate = DateTime.Parse("2002-09-01")
                },
                New Student() With {
                    .FirstMidName = "Arturo",
                    .LastName = "Anand",
                    .EnrollmentDate = DateTime.Parse("2003-09-01")
                },
                New Student() With {
                    .FirstMidName = "Gytis",
                    .LastName = "Barzdukas",
                    .EnrollmentDate = DateTime.Parse("2002-09-01")
                },
                New Student() With {
                    .FirstMidName = "Yan",
                    .LastName = "Li",
                    .EnrollmentDate = DateTime.Parse("2002-09-01")
                },
                New Student() With {
                    .FirstMidName = "Peggy",
                    .LastName = "Justice",
                    .EnrollmentDate = DateTime.Parse("2001-09-01")
                },
                New Student() With {
                    .FirstMidName = "Laura",
                    .LastName = "Norman",
                    .EnrollmentDate = DateTime.Parse("2003-09-01")
                },
                New Student() With {
                    .FirstMidName = "Nino",
                    .LastName = "Olivetto",
                    .EnrollmentDate = DateTime.Parse("2005-09-01")
                }
            }
            students.ForEach(Function(s) context.Students.Add(s))
            context.SaveChanges()

            Dim courses = New List(Of Course)() From {
                New Course() With {
                    .CourseID = 1050,
                    .Title = "Chemistry",
                    .Credits = 3
                },
                New Course() With {
                    .CourseID = 4022,
                    .Title = "Microeconomics",
                    .Credits = 3
                },
                New Course() With {
                    .CourseID = 4041,
                    .Title = "Macroeconomics",
                    .Credits = 3
                },
                New Course() With {
                    .CourseID = 1045,
                    .Title = "Calculus",
                    .Credits = 4
                },
                New Course() With {
                    .CourseID = 3141,
                    .Title = "Trigonometry",
                    .Credits = 4
                },
                New Course() With {
                    .CourseID = 2021,
                    .Title = "Composition",
                    .Credits = 3
                },
                New Course() With {
                    .CourseID = 2042,
                    .Title = "Literature",
                    .Credits = 4
                }
            }

            courses.ForEach(Function(s) context.Courses.Add(s))
            context.SaveChanges()

            Dim enrollments = New List(Of Enrollment)() From {
                New Enrollment() With {
                    .StudentID = 1,
                    .CourseID = 1050,
                    .Grade = Grade.A
                },
                New Enrollment() With {
                    .StudentID = 1,
                    .CourseID = 4022,
                    .Grade = Grade.C
                },
                New Enrollment() With {
                    .StudentID = 1,
                    .CourseID = 4041,
                    .Grade = Grade.B
                },
                New Enrollment() With {
                    .StudentID = 2,
                    .CourseID = 1045,
                    .Grade = Grade.B
                },
                New Enrollment() With {
                    .StudentID = 2,
                    .CourseID = 3141,
                    .Grade = Grade.F
                },
                New Enrollment() With {
                    .StudentID = 2,
                    .CourseID = 2021,
                    .Grade = Grade.F
                },
                New Enrollment() With {
                    .StudentID = 3,
                    .CourseID = 1050
                },
                New Enrollment() With {
                    .StudentID = 4,
                    .CourseID = 1050
                },
                New Enrollment() With {
                    .StudentID = 4,
                    .CourseID = 4022,
                    .Grade = Grade.F
                },
                New Enrollment() With {
                    .StudentID = 5,
                    .CourseID = 4041,
                    .Grade = Grade.C
                },
                New Enrollment() With {
                    .StudentID = 6,
                    .CourseID = 1045
                },
                New Enrollment() With {
                    .StudentID = 7,
                    .CourseID = 3141,
                    .Grade = Grade.A
                }
            }
            enrollments.ForEach(Function(s) context.Enrollments.Add(s))
            context.SaveChanges()

        End Sub
    End Class
End Namespace

The Seed method takes the database context object as an input parameter, and the code in the method uses that object to add new entities to the database. For each entity type, the code creates a collection of new entities, adds them to the appropriate DbSet property, and then saves the changes to the database. It isn't necessary to call the SaveChanges method after each group of entities, as is done here, but doing that helps you locate the source of a problem if an exception occurs while the code is writing to the database.

To tell Entity Framework to use your initializer class, add an element to the entityFramework element in the application Web.config file (the one in the root project folder), as shown in the following example:

  <entityFramework>
    <contexts>
      <context type="ContosoUniversity.DAL.SchoolContext, ContosoUniversity">
        <databaseInitializer type="ContosoUniversity.DAL.SchoolInitializer, ContosoUniversity" />
      </context>
    </contexts>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v11.0" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>

The context type specifies the fully qualified context class name and the assembly it's in, and the databaseInitializer type specifies the fully qualified name of the initializer class and the assembly it's in. (When you don't want EF to use the initializer, you can set an attribute on the context element: disableDatabaseInitialization="true".) For more information, see Entity Framework - Config File Settings.

As an alternative to setting the initializer in the Web.config file is to do it in code by adding a Database.SetInitializer statement to the Application_Start method in in the Global.asax.vb file. For more information, see Understanding Database Initializers in Entity Framework Code First.

The application is now set up so that when you access the database for the first time in a given run of the application, the Entity Framework compares the database to the model (your SchoolContext and entity classes). If there's a difference, the application drops and re-creates the database.

Note: When you deploy an application to a production web server, you must remove or disable code that drops and re-creates the database. You'll do that in a later tutorial in this series.

Set up EF to use a SQL Server Express LocalDB database

LocalDB is a lightweight version of the SQL Server Express Database Engine. It's easy to install and configure, starts on demand, and runs in user mode. LocalDB runs in a special execution mode of SQL Server Express that enables you to work with databases as .mdf files. You can put LocalDB database files in the App_Data folder of a web project if you want to be able to copy the database with the project. The user instance feature in SQL Server Express also enables you to work with .mdf files, but the user instance feature is deprecated; therefore, LocalDB is recommended for working with .mdf files. In Visual Studio 2012 and later versions, LocalDB is installed by default with Visual Studio.

Typically SQL Server Express is not used for production web applications. LocalDB in particular is not recommended for production use with a web application because it is not designed to work with IIS.

In this tutorial you'll work with LocalDB. Open the application Web.config file and add a connectionStrings element preceding the appSettings element, as shown in the following example. (Make sure you update the Web.config file in the root project folder. There's also a Web.config file is in the Views subfolder that you don't need to update.)

  <connectionStrings>
    <add name="SchoolContext" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=ContosoUniversity1;Integrated Security=SSPI;" providerName="System.Data.SqlClient"/>
  </connectionStrings>
  <appSettings>
    <add key="webpages:Version" value="3.0.0.0" />
    <add key="webpages:Enabled" value="false" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
  </appSettings>

The connection string you've added specifies that Entity Framework will use a LocalDB database named ContosoUniversity1.mdf. (The database doesn't exist yet; EF will create it.) If you wanted the database to be created in your App_Data folder, you could add  AttachDBFilename=|DataDirectory|\ContosoUniversity1.mdf to the connection string. For more information about connection strings, see SQL Server Connection Strings for ASP.NET Web Applications.

You don't actually have to have a connection string in the Web.config file. If you don't supply a connection string, Entity Framework will use a default one based on your context class. For more information, see Code First to a New Database.  

Creating a Student Controller and Views

Now you'll create a web page to display data, and the process of requesting the data will automatically trigger
the creation of the database. You'll begin by creating a new controller. But before you do that, build the project to make the model and context classes available to MVC controller scaffolding.

  1. Right-click the Controllers folder in Solution Explorer, select Add, and then click New Scaffolded Item.
  2. In the Add Scaffold dialog box, select MVC 5 Controller with views, using Entity Framework.
  3. MVC5 With EF6

  4. In the Add Controller dialog box, make the following selections and then click Add:
    • Controller name: StudentController.
    • Model class: Student (ContosoUniversity.Models). (If you don't see this option in the drop-down list, build the project and try again.)
    • Data context class: SchoolContext (ContosoUniversity.DAL).
    • Leave the default values for the other fields.   

    MVC5 With EF6

    When you click Add, the scaffolder creates a StudentController.vb file and a set of views (.vbhtml files) that work with the controller. In the future when you create projects that use Entity Framework you can also take advantage of some additional functionality of the scaffolder:  just create your first model class, don't create a connection string, and then in the Add Controller box specify new context class.  The scaffolder will create your DbContext class and your connection string as well as the controller and views.

     

  5. Visual Studio opens the Controllers\StudentController.vb file. You see a class variable has been created that instantiates a database context object:
    Private db As New SchoolContext

    The Index action method gets a list of students from the Students entity set by reading the Students property of the database context instance:

    Function Index() As ActionResult
        Return View(db.Students.ToList())
    End Function

    The Student\Index.vbhtml view displays this list in a table:

    <table class="table">
        <tr>
            <th>
                @Html.DisplayNameFor(Function(model) model.LastName)
            </th>
            <th>
                @Html.DisplayNameFor(Function(model) model.FirstMidName)
            </th>
            <th>
                @Html.DisplayNameFor(Function(model) model.EnrollmentDate)
            </th>
            <th></th>
        </tr>
    
    @For Each item In Model
        @<tr>
            <td>
                @Html.DisplayFor(Function(modelItem) item.LastName)
            </td>
            <td>
                @Html.DisplayFor(Function(modelItem) item.FirstMidName)
            </td>
            <td>
                @Html.DisplayFor(Function(modelItem) item.EnrollmentDate)
            </td>
            <td>
                @Html.ActionLink("Edit", "Edit", New With {.id = item.ID }) |
                @Html.ActionLink("Details", "Details", New With {.id = item.ID }) |
                @Html.ActionLink("Delete", "Delete", New With {.id = item.ID })
            </td>
        </tr>
    Next
    </table>
  6. Press CTRL+F5 to run the project. (If you get a "Cannot create Shadow Copy" error, close the browser and try again.)

    Click the Students tab to see the test data that the Seed method inserted. Depending on how narrow your browser window is, you'll see the Student tab link in the top address bar or you'll have to click the upper right corner to see the link.

    MVC5 With EF6

    MVC5 With EF6

View the Database

When you ran the Students page and the application tried to access the database, EF saw that there was no database and so it created one, then it ran the seed method to populate the database with data.

You can use either Server Explorer or SQL Server Object Explorer (SSOX) to view the database in Visual Studio. For this tutorial you'll use Server Explorer. (In Visual Studio Express editions earlier than 2013, Server Explorer is called Database Explorer.)

  1. Close the browser.
  2. In Server Explorer, expand Data Connections, expand School Context (ContosoUniversity), and then expand Tables to see the tables in your new database.

    MVC5 With EF6

  3. Right-click the Student table and click Show Table Data to see the columns that were created and the rows that were inserted into the table.

    MVC5 With EF6

  4. Close the Server Explorer connection.

The ContosoUniversity1.mdf and .ldf database files are in the C:\Users\<yourusername> folder.

Because you're using the DropCreateDatabaseIfModelChanges initializer, you could now make a change to the Student class, run the application again, and the database would automatically be re-created to match your change. For example, if you add an EmailAddress property to the Student class, run the Students page again, and then look at the table again, you will see a new EmailAddress column.

Conventions

The amount of code you had to write in order for the Entity Framework to be able to create a complete database for you is minimal because of the use of conventions, or assumptions that the Entity Framework makes. Some of them have already been noted or were used without you being aware of them:

  • The pluralized forms of entity class names are used as table names.
  • Entity property names are used for column names.
  • Entity properties that are named ID or classnameID are recognized as primary key properties. 
  • A property is interpreted as a foreign key property if it's named <navigation property name><primary key property name> (for example, StudentID for the Student navigation property since the Student entity's primary key is ID). Foreign key properties can also be named the same simply <primary key property name> (for example, EnrollmentID since the Enrollment entity's primary key is EnrollmentID).

You've seen that conventions can be overridden. For example, you specified that table names shouldn't be pluralized, and you'll see later how to explicitly mark a property as a foreign key property. You'll learn more about conventions and how to override them in the Creating a More Complex Data Model tutorial later in this series.  For more information about conventions, see Code First Conventions.

Summary

You've now created a simple application that uses the Entity Framework and SQL Server Express LocalDB to store and display data. In the next tutorial you'll learn how to perform basic CRUD (create, read, update, delete) operations. 

 

Date Posted: Friday, June 13, 2014 1:33 PM
Last Updated:
Posted by: Mikesdotnetting
Total Views to date: 11698

4 Comments

Thursday, June 26, 2014 11:12 AM - Alek Dmowski

Hi Mike,
I'd like to thank You for your hard work in this and previous tutorials.
It is really helpful for me and (i'm sure) others.
btw. MVC is first technology I've seen in MS (and Telerik) without VB suport, don't you know why?

Cheers
Alek

Thursday, June 26, 2014 1:25 PM - Mike

@Alek,

Previous versions of the tutorials have been published in both C# and VB versions. The documentation team were unable to do so with the latest versions due to "time limitations and other priorities". That's why I volunteered to do it.

Friday, June 27, 2014 10:29 PM - Ryan

Thank you for this conversion. I have learned a lot from this. I could have followed the C# code from MS and tried converting to VB.NET as I went, but this saved me the hassle and allowed me to focus on the concepts. I appreciate it.

Monday, October 20, 2014 9:53 PM - Jeroen

Hi Mike,
Would it be possible to add or extend the tutorial with an admincontroller to add users to roles? I tried to translate the identitysamples project myself, but learning MVC, EF and identity at the same time is like learning to swim while a Russian swimminginstructor wants me to sing the French national hymne. I'm drowning.
I don't understand why the default VB template contains logic to login and register, but nothing to administrate users and roles.

Regards,
Jeroen
Add your comment

If you have any comments to make about this article, please use this form to do so. Make sure that your comment relates specifically to the article above. More general comments can be posted through the form on the Contact page.

Please note, all comments are moderated, and some may not be published. The kind of things that will ensure your comment is deleted without ever seeing the light of day are as follows:

  • Not relevant to the article
  • Gratuitous links to your own site or product
  • Anything abusive or libellous
  • Spam
  • Anything in a language I don't understand including gibberish.

I do not pass email addresses on to spammers, so a valid one will assist me in responding to you personally if required.

Recent Comments

Allen Michaels 12/17/2014 4:37 PM
In response to Cascading DropDownLists with jQuery and ASP.NET
Fantastic thank you so much!...

Emily 12/17/2014 12:36 PM
In response to Parameterized IN clauses with ADO.NET and LINQ
Thanks, very helpful!!!! Can i use this for multiple in's ????? IN (.....) and IN(...) and IN...

sss 12/16/2014 3:06 PM
In response to Solving the Operation Must Use An Updateable Query error
good...

Gjuro 12/15/2014 10:30 PM
In response to Examining the Edit Methods and Edit View
You have one fromr (and it should be from, I suppose). :-)...

Gjuro 12/15/2014 10:27 PM
In response to Adding Search
Hi, thnx for all this C#->VB translations. Yet, the following code block is (slightly) in error it a...

Scot 12/14/2014 1:39 PM
In response to Entity Framework 6 Recipe - Alphabetical Paging In ASP.NET MVC
Thanks,Mike I found solution....

Gjuro 12/13/2014 10:52 PM
In response to Accessing Your Model's Data from a Controller
The article mentions "Creating an Entity Framework Data Model for an ASP.NET MVC Application" (at is...

Samuel 12/13/2014 8:40 AM
In response to Displaying The First n Characters Of Text
I have failed to use the extension because it throws an error that it doesn't recognise the chop be...

Ignas 12/12/2014 5:11 PM
In response to Cleaner Conditional HTML Attributes In Razor Web Pages
Any suggestions for Html Helper elements with HtmlAttributes, when you need to conditionally set it...

Gautam 12/11/2014 8:50 PM
In response to Validation In Razor Web Pages 2
Hi Mike Is this required for V3, non html helper input...