ASPNET - Databases Cheatsheet
ASPNET - Databases Cheatsheet
NET I
ASP.NET: Databases
Database Model
Entity Framework uses C# classes to define the
database model. This is an in-memory representation using System;
of data stored in a database table. Several model
classes combine to form the schema for the database. public class Country
Each property maps to a column in a database table. {
The bottom line in the example shows a type of
public string ID { get; set; }
Continent which implies a relationship to another
public string ContinentID { get; set; }
table.
public string Name { get; set; }
public int? Population { get; set; }
public int? Area { get; set; }
public DateTime? UnitedNationsDate
{ get; set; }
Model Binding
In ASP.NET Core, model binding is a feature that
simplifies capturing and storing data in a web app. The
process of model binding includes retrieving data from
various sources, converting them to collections of .NET
types, and passing them to controllers/page models.
Helpers and attributes are used to render HTML with
the contents of bound page models. Client- and
server-side validation scripts are used to ensure
integrity during data entry.
Adding Records
The Entity Framework context DbSet member provides
the Add() and AddAsync() methods to insert a new // Assuming Country is of type Country
record into the in-memory representation of the // Assuming _context is of a type
corresponding database table. A batch of multiple inheriting DbSet
records can also be added in this fashion.
The record is passed from the browser in the <form>
public async Task<IActionResult>
post back. In this case a Country member is declared
OnPostAsync(string id)
with a [BindProperty] attribute so the entire record is
{
passed back to the server.
if (!ModelState.IsValid)
Use the EF context SaveChanges() or
SaveChangesAsync() methods to persist all new records {
to the database table. return Page();
}
await
_context.Countries.AddAsync(Country);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
Saving Changes
The Entity Framework context DbSet member provides
the Attach() method to update an existing record, the // Assuming Country is of type Country
Add() method to insert a new record, and the // Assuming _context is of a type
Remove() method to delete an existing record. Any inheriting DbSet
combination of multiple records can batched before
saving.
public async Task<IActionResult>
Use the EF context SaveChanges() or
OnPostAsync(string id)
SaveChangesAsync() methods to persist all inserted,
{
updated, and deleted records to the database table.
// update
_context.Attach(Country).State
= EntityState.Modified;
// insert
await
_context.Countries.AddAsync(Country);
// delete
Country Country = await
_context.Countries.FindAsync(id);
if (Country != null)
{
_context.Countries.Remove(Country);
}
return RedirectToPage("./Index");
}
Finding Records
The Entity Framework context DbSet member provides
the Find() and FindAsync() methods to retrieve an // Assuming Country is of type Country
existing record from the in-memory representation of // Assuming _context is of a type
the database table. Assign the result of this method to a inheriting DbSet
local member in the page model.
This method generates the appropriate SQL syntax
public async Task<IActionResult>
needed to access the record in the database table.
OnGetAsync(string id)
{
if (id == null)
{
return NotFound();
}
return Page();
}
Deleting Records
The Entity Framework context DbSet member provides
the Remove() method to delete an existing record from // Assuming Country is of type Country
the in-memory representation of the database table. // Assuming _context is of a type
Any combination of multiple record deletions can be inheriting DbSet
batched before saving.
Use the EF context SaveChanges() or
public async Task<IActionResult>
SaveChangesAsync() methods to persist all deletions to
OnPostAsync(string id)
the database table.
{
if (id == null)
{
return NotFound();
}
if (Country != null)
{
_context.Countries.Remove(Country);
}
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
Updating Records
The Entity Framework context DbSet member provides
the Attach() method to update an existing record in // Assuming Country is of type Country
the in-memory representation of the corresponding // Assuming _context is of a type
database table. A batch of multiple records can also be inheriting DbSet
updated in this fashion.
The record is passed from the browser in the <form>
public async Task<IActionResult>
post back. In this case a Country member is declared
OnPostAsync(string id)
with a [BindProperty] attribute so the entire record is
{
passed back to the server.
if (!ModelState.IsValid)
Use the EF context SaveChanges() or
SaveChangesAsync() methods to persist all updated {
records to the database table. return Page();
}
_context.Attach(Country).State
= EntityState.Modified;
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
[Display] Attribute
The [Display] attribute specifies the caption for a
label, textbox, or table heading. using
Within a Razor Page, the @Html.DisplayForName() System.ComponentModel.DataAnnotations;
helper defaults to the property name unless the
[Display] attribute overrides it. In this case, public class Country
Continent is displayed instead of the more technical
{
ContinentID .
[Display(Name = "Continent")]
public string ContinentID { get; set; }
}
[DisplayFormat] Attribute
The [DisplayFormat] attribute can explicitly apply a C#
format string. The optional ApplyFormatInEditMode using
means the format should also apply in edit mode. System.ComponentModel.DataAnnotations;
[DisplayFormat] is often used in combination with the
[DataType] attribute. Together they determine the
public class Country
rendered HTML when using the @Html.DisplayFor()
{
helper.
[DisplayFormat(DataFormatString = "
{0:N0}", ApplyFormatInEditMode = true)]
public int? Population { get; set; }
}
[DataType] Attribute
The [DataType] attribute specifies a more specific
data type than the database column type. In this case, using
the database table will use a DateTime column but the System.ComponentModel.DataAnnotations;
render logic will only show the date.
The @Html.DisplayFor() helper knows about types and public class Country
will render a default format to match the type. In this
{
case, the HTML5 browser date picker will appear when
[DataType(DataType.Date)]
editing the field.
[DisplayFormat(DataFormatString = "
{0:yyyy-MM-dd}", ApplyFormatInEditMode
= true)]
public DateTime? UnitedNationsDate
{ get; set; }
}
[Required] Attribute
The [Required] attribute can be applied to one or
more properties in a database model class. EF will using
create a NOT NULL column in the database table for the System.ComponentModel.DataAnnotations;
property.
The client-side JavaScript validation scripts will ensure public class Country
that a non-empty string or number is valid before
{
posting the record from the browser on inserts and
[Required]
updates.
public string Name { get; set; }
}
[RegularExpression] Attribute
The [RegularExpression] attribute can apply detailed
restrictions for data input. The match expression is using
evaluated during data entry and the result returns true System.ComponentModel.DataAnnotations;
or false. If false, the model state will not be valid and
the optional ErrorMessage will display. public class Country
In a Razor page, the @Html.DisplayFor() helper only
{
shows the data in the field. The asp-validation-for
[RegularExpression(@"[A-Z]+",
attribute on a <span> tag displays the ErrorMessage .
ErrorMessage = "Only upper case
characters are allowed.")]
public string CountryCode { get; set; }
}
[StringLength] Attribute
The [StringLength] attribute specifies the maximum
length of characters that are allowed in a data field and using
optionally the minimum length. The model will not be System.ComponentModel.DataAnnotations;
flagged as valid if these restrictions are exceeded. In
this case, the ContinentID must be exactly 2 public class Country
characters in length.
{
In a Razor Page, the @Html.DisplayFor() helper only
[StringLength(2, MinimumLength = 2)]
shows the data in the field. The client-side JavaScript
public string ContinentCode { get; set;
validation scripts use the asp-validation-for attribute
}
on a <span> tag to display a default error message.
}
[Range] Attribute
The [Range] attribute specifies the minimum and
maximum values in a data field. The model will not be using
flagged as valid if these restrictions are exceeded. In System.ComponentModel.DataAnnotations;
this case, Population must be greater than 0 and less
than the big number! public class Country
In a Razor page, the @Html.DisplayFor() helper only
{
shows the data in the field. The client-side JavaScript
[Range(1, 10000000000)]
validation scripts use the asp-validation-for attribute
public int? Population { get; set; }
on a <span> tag to display a default error message.
}
Select List Items Attribute
<select asp-
for="Country.ContinentID" asp-
items="Model.Continents">
</select>
using
Microsoft.AspNetCore.Mvc.Renderin
g;
<select class="valid"
id="Country_ContinentID"
name="Country.ContinentID" aria-
invalid="false">
<option value="NA">North
America</option>
<option value="SA">South
America</option>
<option
value="EU">Europe</option>
<!-- etc -->
</select>
LINQ Queries
The Entity Framework DbSet entities can manage
complex queries using C# LINQ syntax. This is using System.Linq;
referenced from the System.Linq library.
All of the Where() and OrderBy() clauses are var countries = from c in
evaluated in the final statement that calls _context.Countries
ToListAsync() . EF evaluates all options and generates
select c;
a SQL SELECT statement with corresponding WHERE
and ORDERBY clauses.
countries = countries.Where(c =>
c.Name.Contains("Russia"));
DisplayNameFor Helper
The @Html.DisplayNameFor() tag helper is used to
display the friendly name for a property in a database <!-- In .cshtml file -->
model. By default, this will match the property name. If <div>
a [Display(Name = "Code")] annotation is applied to @Html.DisplayNameFor(model =>
the property in the model class, that string is used model.Continent.ID)
instead
</div>