Skip to main content This browser is no longer supported. Show
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Tutorial: Create a more complex data model for an ASP.NET MVC app
In this articleIn the previous tutorials you worked with a simple data model that was composed of three entities. In this tutorial you add more entities and relationships and you customize the data model by specifying formatting, validation, and database mapping rules. This article shows two ways to customize the data model: by adding attributes to entity classes and by adding code to the database context class. When you're finished, the entity classes will make up the completed data model that's shown in the following illustration: In this tutorial, you:
Prerequisites
Customize the data modelIn this section you'll see how to customize the data model by using attributes that specify formatting, validation, and database mapping rules.
Then in several of the following sections you'll create the complete The DataType AttributeFor student enrollment dates, all of the web pages currently display the time along with the date, although all you care about for this field is the date. By using data annotation attributes, you can make one code change
that will fix the display format in every view that shows the data. To see an example of how to do that, you'll add an attribute to the In Models\Student.cs, add a
The
DataType attribute is used to specify a data type that is more specific than the database intrinsic type. In this case we only want to keep track of the date, not the date and time. The DataType Enumeration
provides for many data types, such as Date, Time, PhoneNumber, Currency, EmailAddress and more. The
The
The You can use the DisplayFormat attribute by itself, but it's generally a good idea to use the
DataType attribute also. The
If you use the For more information about how to handle other date formats in MVC, go to MVC 5 Introduction: Examining the Edit Methods and Edit View and search in the page for "internationalization". Run the Student Index page again and notice that times are no longer displayed for the enrollment dates. The same will be true for any view that uses the The StringLengthAttributeYou can also specify data validation rules and validation error messages using attributes. The StringLength attribute sets the maximum length in the database and provides client side and server side validation for ASP.NET MVC. You can also specify the minimum string length in this attribute, but the minimum value has no impact on the database schema. Suppose you want to ensure that users don't enter more than 50 characters for a
name. To add this limitation, add StringLength attributes to the
The StringLength attribute won't prevent a user from entering white space for a name. You can use the RegularExpression attribute to apply restrictions to the input. For example the following code requires the first character to be upper case and the remaining characters to be alphabetical:
The MaxLength attribute provides similar functionality to the StringLength attribute but doesn't provide client side validation. Run the application and click the Students tab. You get the following error: The model backing the 'SchoolContext' context has changed since the database was created. Consider using Code First Migrations to update the database (https://go.microsoft.com/fwlink/?LinkId=238269). The database model has changed in a way that requires a change in the database schema, and Entity Framework detected that. You'll use
migrations to update the schema without losing any data that you added to the database by using the UI. If you changed data that was created by the In the Package Manager Console (PMC), enter the following commands:
The The timestamp prepended to the migrations file name is used by Entity Framework to order the migrations. You can create multiple migrations before running the Run the Create page, and enter either name longer than 50 characters. When you click Create, client side validation shows an error message: The field LastName must be a string with a maximum length of 50. The Column AttributeYou can also use attributes to control how your classes and properties are mapped to the database. Suppose you had used the name The In the Student.cs file, add a
The addition of the Column attribute changes the model backing the SchoolContext, so it won't match the database. Enter the following commands in the PMC to create another migration:
In Server Explorer, open the Student table designer by double-clicking the Student table. The following image shows the original column name as it was before you applied the first two migrations. In addition to the column name changing from You can also make database mapping changes using the Fluent API, as you'll see later in this tutorial. Note If you try to compile before you finish creating all of the entity classes in the following sections, you might get compiler errors. Update Student entityIn Models\Student.cs, replace the code you added earlier with the following code. The changes are highlighted.
The Required AttributeThe Required attribute makes the name properties required fields. The The
The Display AttributeThe The FullName Calculated Property
Create Instructor entityCreate Models\Instructor.cs, replacing the template code with the following code:
Notice that several properties are the
same in the You can put multiple attributes on one line, so you could also write the instructor class as follows:
The Courses and OfficeAssignment Navigation PropertiesThe An instructor can teach any number of courses, so
Our business rules state an instructor can only have at most one office, so
Create OfficeAssignment entityCreate Models\OfficeAssignment.cs with the following code:
Build the project, which saves your changes and verifies you haven't made any copy and paste errors the compiler can catch. The Key AttributeThere's a one-to-zero-or-one relationship between the
You can also use the The ForeignKey AttributeWhen there is a one-to-zero-or-one relationship or a one-to-one relationship between two entities (such as between Unable to determine the principal end of an association between the types 'ContosoUniversity.Models.OfficeAssignment' and 'ContosoUniversity.Models.Instructor'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations. Later in the tutorial you'll see how to configure this relationship with the fluent API. The Instructor Navigation PropertyThe You could put a Modify the Course entityIn Models\Course.cs, replace the code you added earlier with the following code:
The course entity has a foreign key property The DatabaseGenerated AttributeThe
DatabaseGenerated attribute with the None parameter on the
By default, the Entity Framework assumes that primary key values are generated by the database. That's what you want in most scenarios. However, for Foreign Key and Navigation PropertiesThe foreign key properties and navigation properties in the
Create the Department entityCreate Models\Department.cs with the following code:
The Column AttributeEarlier you used the Column attribute to change column name mapping. In the code for the
Column mapping is generally not required, because the Entity Framework usually chooses the appropriate SQL Server data type based on the CLR type that you define for the property. The CLR Foreign Key and Navigation PropertiesThe foreign key and navigation properties reflect the following relationships:
Modify the Enrollment entityIn Models\Enrollment.cs, replace the code you added earlier with the following code
Foreign Key and Navigation PropertiesThe foreign key properties and navigation properties reflect the following relationships:
Many-to-Many RelationshipsThere's
a many-to-many relationship between the The following illustration shows what these relationships look like in an entity diagram. (This diagram was generated using the Entity Framework Power Tools; creating the diagram isn't part of the tutorial, it's just being used here as an illustration.) Each relationship line has a 1 at one end and an asterisk (*) at the other, indicating a one-to-many relationship. If the A join table is required in the database, however, as shown in the following database diagram: The Entity Framework automatically creates the Entity relationship diagramThe following illustration shows the diagram that the Entity Framework Power Tools create for the completed School model. Besides the many-to-many
relationship lines (* to *) and the one-to-many relationship lines (1 to *), you can see here the one-to-zero-or-one relationship line (1 to 0..1) between the Add code to database contextNext you'll add the new entities to the
In this tutorial you'll use the fluent API only for database mapping that you can't do with attributes. However, you can also use the fluent API to specify most of the formatting, validation, and mapping rules that you can do by
using attributes. Some attributes such as Some developers prefer to use the fluent API exclusively so that they can keep their entity classes "clean." You can mix attributes and fluent API if you want, and there are a few customizations that can only be done by using fluent API, but in general the recommended practice is to choose one of these two approaches and use that consistently as much as possible. To add the new entities to the data model and perform database mapping that you didn't do by using attributes, replace the code in DAL\SchoolContext.cs with the following code:
The new statement in the OnModelCreating method configures the many-to-many join table:
The following code provides an example of how you could have used fluent API instead of attributes to specify the
relationship between the
For information about what "fluent API" statements are doing behind the scenes, see the Fluent API blog post. Seed database with test dataReplace the code in the Migrations\Configuration.cs file with the following code in order to provide seed data for the new entities you've created.
As you saw in the first tutorial, most of this code simply updates or creates new entity objects and loads sample data into properties as required for testing. However, notice how the
When you create a Add a migrationFrom the PMC, enter the
If you tried to run the The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK_dbo.Course_dbo.Department_DepartmentID". The conflict occurred in database "ContosoUniversity", table "dbo.Department", column 'DepartmentID'. Sometimes when you execute migrations with existing data, you need to insert stub data
into the database to satisfy foreign key constraints, and that's what you have to do now. The generated code in the ComplexDataModel Edit the <timestamp>_ComplexDataModel.cs file, comment out the line of code that adds the DepartmentID column to the Course table, and add the following highlighted code (the commented line is also highlighted):
When the
Update the databaseAfter you have finished editing the <timestamp>_ComplexDataModel.cs file, enter the
Note It's possible to get other errors when migrating data and making schema changes. If you get migration errors you can't resolve, you can either change the database name in the connection string or delete the database. The simplest approach is to rename the database in Web.config file. The following example shows the name changed to CU_Test:
With a new database, there is no data to migrate, and the If that fails, another thing you can try is re-initialize the database by entering the following command in the PMC:
Open the database in Server Explorer as you did earlier, and expand the Tables node to see that all of the tables have been created. (If you still have Server Explorer open from the earlier time, click the Refresh button.) You didn't create a model
class for the Right-click the Get the codeDownload Completed Project Additional resourcesLinks to other Entity Framework resources can be found in the ASP.NET Data Access - Recommended Resources. Next stepsIn this tutorial, you:
Advance to the next article to learn how to read and display related data that the Entity Framework loads into navigation properties. Additional resourcesAdditional resourcesIn this articleWhich of the following programs allow designers to rotate designs of 3D objects?Adobe Aero is software that enables you to draw 3D designs. It allows you to rotate and transform the objects.
Which of the following kinds of programs displays an online advertisement in a banner or pop up window on webpages email or other Internet service?Adware is any software application in which an advertising banner or other advertising material displays or downloads while a program is running.
Which of the following is a utility that allows users to display copy and print the contents of a graphics file?An image viewer is a utility that allows users to display, copy, and print the contents of a graphics file, such as a photo.
Which of the following is a request for specific data from a database?A select query is one that retrieves data from a database.
|