Model Review

Write a model class with one property for each column, choosing C# types that match the SQL types, and nullable types for columns that allow NULL.

Journeyman · C# · T-SQL · Updated

After this lesson you can

  • Write a model class whose properties match a table's columns

Key takeaways

  • A model has an auto-property for each column, with the column's name and a C# type that matches its SQL type, such as decimal for money.
  • A column that allows NULL gets a ? on its type: string? for Description, decimal? for UnitPrice.
  • A text column that never allows NULL is a plain string, started at "" so it's never null.
  • Models usually live in a Models folder, one class per file, with a namespace that matches the folder, such as NorthwindReport.Models.

A model is an ordinary class, of the kind you wrote in Encapsulation and Classes, with an auto-property for each column. Here's the Categories table, as SSMS shows it under Columns:

Column SQL type Allows NULL
CategoryId int (identity) no
CategoryName nvarchar(15) no
Description ntext yes
Picture image yes

And its model, leaving out the picture, which this program doesn't need:

public class Category
{
    public int CategoryId { get; set; }
    public string CategoryName { get; set; } = "";
    public string? Description { get; set; }
}

Choosing each property's type

Match each column's SQL type with its C# type, as in the table in ADO.NET Objects: int for int, string for nvarchar and ntext, decimal for money, bool for bit, DateTime for datetime.

Then ask whether the column allows NULL:

  • No: use the plain type. CategoryName always has a value, so it's a string, started at "" so it's never null.
  • Yes: add a ?. Description might be missing, so it's a string?. For value types such as int and decimal, the ? makes a nullable type: decimal? can hold a price, or null for no price.

Here is the Products table's model. Look at which properties are nullable:

public class Product
{
    public int ProductId { get; set; }
    public string ProductName { get; set; } = "";
    public int? SupplierId { get; set; }
    public int? CategoryId { get; set; }
    public string? QuantityPerUnit { get; set; }
    public decimal? UnitPrice { get; set; }
    public short? UnitsInStock { get; set; }
    public short? UnitsOnOrder { get; set; }
    public short? ReorderLevel { get; set; }
    public bool Discontinued { get; set; }
}

ProductId, ProductName and Discontinued are required in the table, so their properties are plain. Every other column allows NULL, so its property can hold null too. UnitsInStock is a smallint in SQL Server, a small whole number, which is a short in C#.

Where models live

In a project, models usually get a folder of their own, Models, with one class per file: Models/Category.cs, Models/Product.cs. Each file starts with a namespace that matches its folder:

namespace NorthwindReport.Models;

public class Category
{
    public int CategoryId { get; set; }
    public string CategoryName { get; set; } = "";
    public string? Description { get; set; }
}

Other files use the models with using NorthwindReport.Models;.

Check yourself

1 question to try on the lesson page.

So what

A good model is a faithful copy of a row's shape: the same names, matching types, and a ? wherever the database allows a value to be missing.

Key terms

Cheat sheets