Back to Aspnetcore

Visual Studio

aspnetcore/tutorials/razor-pages/model/includes/model7.md

latest17.7 KB
Original Source

:::moniker range="= aspnetcore-7.0"

In this tutorial, classes are added for managing movies in a database. The app's model classes use Entity Framework Core (EF Core) to work with the database. EF Core is an object-relational mapper (O/RM) that simplifies data access. You write the model classes first, and EF Core creates the database.

The model classes are known as POCO classes (from "Plain-Old CLR Objects") because they don't have a dependency on EF Core. They define the properties of the data that are stored in the database.

Add a data model

Visual Studio

  1. In Solution Explorer, right-click the RazorPagesMovie project > Add > New Folder. Name the folder Models.

  2. Right-click the Models folder. Select Add > Class. Name the class Movie.

  3. Add the following properties to the Movie class:

    [!code-csharp]

The Movie class contains:

  • The ID field is required by the database for the primary key.

  • A [DataType] attribute that specifies the type of data in the ReleaseDate property. With this attribute:

    • The user isn't required to enter time information in the date field.
    • Only the date is displayed, not time information.
  • The question mark after string indicates that the property is nullable. For more information, see Nullable reference types.

DataAnnotations are covered in a later tutorial.

Build the project to verify there are no compilation errors.

Visual Studio Code

  1. Add a folder named Models.
  2. Add a class to the Models folder named Movie.cs.

Add the following properties to the Movie class:

[!code-csharp]

The Movie class contains:

  • An ID field to provide a primary key for the database.

  • A [DataType] attribute to specify the type of data in the ReleaseDate field. With this attribute:

    • The user is not required to enter time information in the date field.
    • Only the date is displayed, not time information.
  • The question mark after string indicates that the property is nullable. For more information, see Nullable reference types.

DataAnnotations are covered in a later tutorial.

<a name="dc7"></a>

Add NuGet packages and EF tools

[!INCLUDE]

In Visual Studio Code, press <kbd>Ctrl</kbd>+<kbd>F5</kbd> to run the app without debugging.

In the Panel below the editor region, select the PROBLEMS tab, or from the View menu, select Problems if it is not currently in view. Verify there are no compilation errors.

Visual Studio for Mac

  1. In the Solution Tool Window, control-click the RazorPagesMovie project, and then select Add > New Folder.... Name the folder Models.

  2. Control-click the Models folder, and then select Add > New Class....

  3. In the New File dialog:

    1. Select General in the left pane.
    2. Select Empty Class in the center pane.
    3. Name the class Movie and select Create.
  4. Add the following properties to the Movie class:

    [!code-csharp]

The Movie class contains:

  • An ID field to provide a primary key for the database.

  • A [DataType] attribute to specify the type of data in the ReleaseDate field. With this attribute:

    • The user isn't required to enter time information in the date field.
    • Only the date is displayed, not time information.

DataAnnotations are covered in a later tutorial.

Build the project to verify there are no compilation errors.


Scaffold the movie model

In this section, the movie model is scaffolded. That is, the scaffolding tool produces pages for Create, Read, Update, and Delete (CRUD) operations for the movie model.

Visual Studio

  1. Create the Pages/Movies folder:

    1. Right-click on the Pages folder > Add > New Folder.
    2. Name the folder Movies.
  2. Right-click on the Pages/Movies folder > Add > New Scaffolded Item.

  3. In the Add New Scaffold dialog, select Razor Pages using Entity Framework (CRUD) > Add.

  4. Complete the Add Razor Pages using Entity Framework (CRUD) dialog:

    1. In the Model class drop down, select Movie (RazorPagesMovie.Models).
    2. In the Data context class row, select the + (plus) sign.
      1. In the Add Data Context dialog, the class name RazorPagesMovie.Data.RazorPagesMovieContext is generated.
      2. In the Database provider drop down, select SQL Server.
    3. Select Add.

The appsettings.json file is updated with the connection string used to connect to a local database.

Visual Studio Code

  • Open a command shell to the project directory, which contains the Program.cs and .csproj files. Run the following command:

    dotnetcli
    dotnet aspnet-codegenerator razorpage -m Movie -dc RazorPagesMovie.Data.RazorPagesMovieContext -udl -outDir Pages/Movies --referenceScriptLibraries --databaseProvider sqlite
    

<a name="codegenerator"></a> The following table details the ASP.NET Core code generator options.

OptionDescription
-mThe name of the model.
-dcThe DbContext class to use including namespace.
-udlUse the default layout.
-outDirThe relative output folder path to create the views.
--referenceScriptLibrariesAdds _ValidationScriptsPartial to Edit and Create pages

Use the -h option to get help on the dotnet aspnet-codegenerator razorpage command:

dotnetcli
dotnet aspnet-codegenerator razorpage -h

For more information, see dotnet aspnet-codegenerator.

[!INCLUDE]

Visual Studio for Mac

<!-- Author note 5-30-23: As of VS 2022 and the 7.05 packages, EF scaffolding on the Mac loads all packages needed including SQLite 7.0.5, but then can't find SQLite and will not scaffold the files. Workaround is add Microsoft.EntityFrameworkCore.Sqlite as a step before scaffolding. Remove once this issue is fixed. -->
  1. Add the NuGet package Microsoft.EntityFrameworkCore.Sqlite, which is required for the scaffolding tool.

    1. In the Solution Tool Window, control-click the RazorPagesMovie project, and then select Open in Terminal.

    The Terminal window opens with the command prompt at the project directory, which contains the Program.cs and .csproj files.

    1. Run the following .NET CLI command:
    dotnetcli
      dotnet add package Microsoft.EntityFrameworkCore.SQLite
    
  2. Create a Pages/Movies folder:

    1. Control-click on the Pages folder > Add > New Folder.
    2. Name the folder Movies.
  3. Control-click on the Pages/Movies folder > Add > New Scaffolding....

  4. In the New Scaffolding dialog, select Razor Pages using Entity Framework (CRUD) > Next.

  5. Complete the Add Razor Pages using Entity Framework (CRUD) dialog:

    1. In the Model class to use: row, enter Movie.
    2. In the DbContext Class to use: row, name the class RazorPagesMovie.Data.RazorPagesMovieContext.
    3. Select Finish.

The scaffolding process may take some time to complete as required packages are automatically downloaded and added to the project.

The appsettings.json file is updated with the connection string used to connect to a local database.

[!INCLUDE]


<!-- ### Fix nullable warnings Build the app. The `Create.cshtml.cs`, `Delete.cshtml.cs`, `Details.cshtml.cs`, `Index.cshtml.cs`, and `Edit.cshtml.cs` files all report a nullable warning when the app is compiled similar to the following: `warning CS8618: Non-nullable property 'Movie' must contain a non-null` value when exiting constructor. Consider declaring the property as nullable. In each of the files, append `= default!;` to the `Movie` declaration. For example: ```diff - public IList<Movie> Movie { get;set; } + public IList<Movie> Movie { get;set; } = default!; - public Movie Movie { get; set; } + public Movie Movie { get; set; } = default!; ``` Fixed in GA per https://github.com/dotnet/Scaffolding/issues/1594#issuecomment-1292422389 -->

[!INCLUDE managed-identities-test-non-production]

Files created and updated

The scaffold process creates the following files:

  • Pages/Movies: Create, Delete, Details, Edit, and Index.
  • Data/RazorPagesMovieContext.cs

The created files are explained in the next tutorial.

The scaffold process adds the following highlighted code to the Program.cs file:

Visual Studio

[!code-csharp]

Visual Studio Code / Visual Studio for Mac

[!code-csharp]


The Program.cs changes are explained later in this tutorial.

<a name="pmc7"></a>

Create the initial database schema using EF's migration feature

The migrations feature in Entity Framework Core provides a way to:

  • Create the initial database schema.
  • Incrementally update the database schema to keep it in sync with the app's data model. Existing data in the database is preserved.

Visual Studio

In this section, the Package Manager Console (PMC) window is used to:

  • Add an initial migration.
  • Update the database with the initial migration.
  1. From the Tools menu, select NuGet Package Manager > Package Manager Console.

  2. In the PMC, enter the following commands:

    powershell
    Add-Migration InitialCreate
    Update-Database
    
  • The Add-Migration command generates code to create the initial database schema. The schema is based on the model specified in DbContext. The InitialCreate argument is used to name the migration. Any name can be used, but by convention a name is selected that describes the migration.

  • The Update-Database command runs the Up method in migrations that have not been applied. In this case, the command runs the Up method in the Migrations/<time-stamp>_InitialCreate.cs file, which creates the database.

Visual Studio Code

  • Right-click the RazorPagesMovie.csproj project, and then select Open in Integrated Terminal.

    The Terminal window opens with the command prompt at the project directory, which contains the Program.cs and .csproj files.

  • Run the following .NET CLI commands:

    dotnetcli
    dotnet ef migrations add InitialCreate
    dotnet ef database update
    
  • The migrations command generates code to create the initial database schema. The schema is based on the model specified in DbContext. The InitialCreate argument is used to name the migrations. Any name can be used, but by convention a name is selected that describes the migration.

  • The update command runs the Up method in migrations that have not been applied. In this case, update runs the Up method in the Migrations/<time-stamp>_InitialCreate.cs file, which creates the database.

[!NOTE] For SQLite, column type for the Price field is set to TEXT. This is resolved in a later step.

Visual Studio for Mac

  • Control-click the RazorPagesMovie project, and then select Open in Terminal.

    The Terminal window opens with the command prompt at the project directory, which contains the Program.cs and .csproj files.

  • Run the following .NET CLI commands:

    dotnetcli
    dotnet tool uninstall --global dotnet-ef
    dotnet tool install --global dotnet-ef
    dotnet ef migrations add InitialCreate
    dotnet ef database update
    
  • The tool commands install the latest Entity Framework Core tools after uninstalling any previous version, if one exists.

    [!INCLUDE]

  • The migrations command generates code to create the initial database schema. The schema is based on the model specified in DbContext. The InitialCreate argument is used to name the migrations. Any name can be used, but by convention a name is selected that describes the migration.

  • The update command runs the Up method in migrations that have not been applied. In this case, update runs the Up method in the Migrations/<time-stamp>_InitialCreate.cs file, which creates the database.

[!NOTE] For SQLite, column type for the Price field is set to TEXT. This is resolved in a later step.


The following warning is displayed, which is addressed in a later step:

No type was specified for the decimal column 'Price' on entity type 'Movie'. This will cause values to be silently truncated if they do not fit in the default precision and scale. Explicitly specify the SQL server column type that can accommodate all the values using 'HasColumnType()'.

The data context RazorPagesMovieContext:

  • Derives from Microsoft.EntityFrameworkCore.DbContext.
  • Specifies which entities are included in the data model.
  • Coordinates EF Core functionality, such as Create, Read, Update and Delete, for the Movie model.

[!code-csharp]

The preceding code creates a DbSet<Movie> property for the entity set. In Entity Framework terminology, an entity set typically corresponds to a database table. An entity corresponds to a row in the table.

The name of the connection string is passed in to the context by calling a method on a DbContextOptions object. For local development, the Configuration system reads the connection string from the appsettings.json file.

<a name="test7"></a>

Test the app

  1. Run the app and append /Movies to the URL in the browser (http://localhost:port/movies).

    If you receive the following error:

    console
    SqlException: Cannot open database "RazorPagesMovieContext-GUID" requested by the login. The login failed.
    Login failed for user 'User-name'.
    

    You missed the migrations step.

  2. Test the Create New link.

    [!NOTE] You may not be able to enter decimal commas in the Price field. To support jQuery validation for non-English locales that use a comma (",") for a decimal point and for non US-English date formats, the app must be globalized. For globalization instructions, see this GitHub issue.

  3. Test the Edit, Details, and Delete links.

The next tutorial explains the files created by scaffolding.

Examine the context registered with dependency injection

ASP.NET Core is built with dependency injection. Services, such as the EF Core database context, are registered with dependency injection during application startup. Components that require these services (such as Razor Pages) are provided via constructor parameters. The constructor code that gets a database context instance is shown later in the tutorial.

The scaffolding tool automatically created a database context and registered it with the dependency injection container. The following highlighted code is added to the Program.cs file by the scaffolder:

Visual Studio

[!code-csharp]

Visual Studio Code / Visual Studio for Mac

[!code-csharp]


Troubleshooting with the completed sample

If you run into a problem you can't resolve, compare your code to the completed project. View or download completed project (how to download).

Next steps

[!div class="step-by-step"] Previous: Get Started Next: Scaffolded Razor Pages

:::moniker-end