This article introduces basic Create, Read, Update and Delete (CRUD) operations using LINQ to SQL in MVC. We are developing an application for User Entity on which we can perform Create, Read, Update and Delete operations.
Create Table
We create a table in a database for the user to store user information. The user table creation code is as in the following:
CREATE TABLE [User]
(
Id int Primary Key Identity(1,1),
Name nvarchar(50) not null,
Age int not null check(Age < 35),
Email nvarchar(50)not null,
CreateOn dateTime default Getdate()
)
Create an MVC Application
I will create a MVC application using Visual Studio 2012. So let's see the procedure for creating a MVC application.
Step 1: Go to "File" -> "New" -> "Project...".
Step 2: Choose "ASP.NET MVC 4 Web Application" from the list, then provide the application name " UserRegistration" and set the path in the location input where you want to create the application.
Step 3: Now choose the Project Template "Empty" and select "Razor" as the view engine from the dropdown list.
Adding a LINQ to SQL Class
Entity classes are created and stored in LINQ to SQL Classes files (.dbml files). The O/R Designer opens when you open a .dbml file. It is a DataContext class that contains methods and properties for connecting to a database and manipulating the data in the database. The DataContext name corresponds to the name that you provided for the .dbml file
Step 1: Right-click on the Models folder in the Solution Explorer then go to "Add" and click on "Class."
Step 2: Choose "LINQ to SQL Classes" from the list and provide the name "User" for the dbml name. After that click on "Add".
Step 3: Drag the User table from the database in the Server Explorer and drop onto the O/R Designer surface of the "User.dbml" file.
Figure 1.1: Table in User.dbml file
Create Model Class
The MVC Model contains all application logic (business logic, validation logic, and data access logic), except pure view and controller logic. We create a class for UserModel (UserModel.cs file) under the Models folder, The UserModel Class is in the Models folder; that file name is UserModel.cs as in the following:
namespace UserRegistration.Models
{
public class UserModel
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public int Age { get; set; }
}
}
Using the Repository Pattern
I implement the Repository pattern by defining one repository class for domain model entity that requires specialized data access methods. A repository class contains the specialized data access methods required for its corresponding domain model entity. When you create the repository class, you create an interface that represents all of the methods used by the repository class. Within your controllers, you write your code against the interface instead of the repository. That way, you can implement the repository using various data access technologies in the future. So first of all you need to create an interface "IUserRepository" under the Models folder that contains basic CRUD operations access methods for user.
using System.Collections.Generic;
namespace UserRegistration.Models
{
public interface IUserRepository
{
IEnumerable<UserModel> GetUsers();
UserModel GetUserById(int userId);
void InsertUser(UserModel user);
void DeleteUser(int userId);
void UpdateUser(UserModel user);
}
}
Thereafter create a repository class "UserRepository" that implements the "IUserRepository" interface under the Models folder.
using System.Collections.Generic;
using System.Linq;
namespace UserRegistration.Models
{
public class UserRepository : IUserRepository
{
private UserDataContext _dataContext;
public UserRepository()
{
_dataContext = new UserDataContext();
}
public IEnumerable<UserModel> GetUsers()
{
IList<UserModel> userList = new List<UserModel>();
var query = from user in _dataContext.Users
select user;
var users = query.ToList();
foreach(var userData in users )
{
userList.Add(new UserModel()
{
Id= userData.Id,
Name = userData.Name,
Email = userData.Email,
Age = userData.Age
});
}
return userList;
}
public UserModel GetUserById(int userId)
{
var query = from u in _dataContext.Users
where u.Id == userId
select u;
var user = query.FirstOrDefault();
var model = new UserModel()
{
Id = userId,
Name = user.Name,
Email = user.Email,
Age = user.Age
};
return model;
}
public void InsertUser(UserModel user)
{
var userData = new User()
{
Name = user.Name,
Email = user.Email,
Age = user.Age
};
_dataContext.Users.InsertOnSubmit(userData);
_dataContext.SubmitChanges();
}
public void DeleteUser(int userId)
{
User user = _dataContext.Users.Where(u => u.Id == userId).SingleOrDefault();
_dataContext.Users.DeleteOnSubmit(user);
_dataContext.SubmitChanges();
}
public void UpdateUser(UserModel user)
{
User userData = _dataContext.Users.Where(u => u.Id == user.Id).SingleOrDefault();
userData.Name = user.Name;
userData.Email = user.Email;
userData.Age = user.Age;
_dataContext.SubmitChanges();
}
}
}
Create Controller and Views for User CRUD operations
You need to create a controller to handle the request from the browser. In this application I created the "UserController" controller under the Controllers folder.
We need the following "using" in the controller to perform CRUD operations:
using System.Data;
using System.Web.Mvc;
using UserRegistration.Models;
We create an instance of the User Repository interface in the User Controller and initialize the user repository in the constructor of the user Controller (UserController.cs) as in the following:
private IUserRepository _repository;
private IUserRepository _repository;
public UserController()
: this(new UserRepository())
{
}
public UserController(IUserRepository repository)
{
_repository = repository;
}
We will use Scaffold templates to create a view for the CRUD operations. We use five scaffold templates, List, Create, Edit, Delete and Details. So create a controller that has post and get action results depending on the operation.
Operation 1: Create New User
Create two actions in the controller, one for the new user to create a view (Get Action) and another for submitting new user details to the repository (Post Action). These have the same name, Create.
public ActionResult Create()
{
return View(new UserModel());
}
[HttpPost]
public ActionResult Create(UserModel user)
{
try
{
if (ModelState.IsValid)
{
_repository.InsertUser(user);
return RedirectToAction("Index");
}
}
catch (DataException)
{
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
}
return View(user);
}
Now we create a view. To create the view use the following procedure:
- Right-click on the Action Method Create (GET).
- The View Name is already filled in so don't change it.
- The View Engine already selected Razor so don't change it.
- Check the checkbox "Create a strongly-typed-view" because we are creating a strongly typed view.
- Choose the Model class "UserModel" so it can be bound with the view.
- Choose "Create" from the Scaffold template so we can do rapid development and we get the view for creating the new user.
- Check both checkboxes "Reference script libraries" and "Use a layout or master page".
@model UserRegistration.Models.UserModel
@{
ViewBag.Title = "Create";
}
<h2>Create</h2>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>UserModel</legend>
<div class="editor-label">
@Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Email)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Email)
@Html.ValidationMessageFor(model => model.Email)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Age)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Age)
@Html.ValidationMessageFor(model => model.Age)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
Run the application and call the create action for the user list.
Figure 1.2 New user create
Operation 2: Show List of All Users
Create an action in the controller named Index. The Index action returns a list of users.
public ActionResult Index()
{
var users = _repository.GetUsers();
return View(users);
}
Now we create a view. To create the view use the following procedure:
- Compile the source code successfully
- Right-click on Action Method Index.
- The View Name is already filled in so don't change it.
- The View Engine already selected Razor so don't change it.
- Check the checkbox "Create a strongly-typed-view" because we are creating a strongly typed view.
- Choose the Model class "UserModel" so it can be bound with the view.
- Choose "List" from the Scaffold template so rapid development can be done and we get the view with the code for showing the list of Users.
- Check both checkboxes "Reference script libraries" and "Use a layout or master page".
@model IEnumerable<UserRegistration.Models.UserModel>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
@Html.DisplayNameFor(model => model.Name)
</th>
<th>
@Html.DisplayNameFor(model => model.Email)
</th>
<th>
@Html.DisplayNameFor(model => model.Age)
</th>
<th></th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Email)
</td>
<td>
@Html.DisplayFor(modelItem => item.Age)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
@Html.ActionLink("Details", "Details", new { id=item.Id }) |
@Html.ActionLink("Delete", "Delete", new { id=item.Id })
</td>
</tr>
}
</table>
Run the application and call the index action for the user list.
Figure 1.3 All User list
Operation 3: Show Details of User
Create an action in the controller named Details. The Details action returns the details of the user.
public ActionResult Details(int id)
{
UserModel model = _repository.GetUserById(id);
return View(model);
}
Now we create the view. To create the view use the following procedure:
- Right-click on Action Method Details.
- The View Name is already filled in so don't change it.
- The View Engine already selected Razor so don't change it.
- Check the checkbox "Create a strongly-typed-view" because we are creating a strongly typed view.
- Choose the Model class "UserModel" so it can be bound with the view.
- Choose "Details" from the Scaffold template so we can do rapid development and we get the view with the code for showing the details of the user.
- Check both the checkboxes "Reference script libraries" and "Use a layout or master page".
@model UserRegistration.Models.UserModel
@{
ViewBag.Title = "Details";
}
<h2>Details</h2>
<fieldset>
<legend>UserModel</legend>
<div class="display-label">
@Html.DisplayNameFor(model => model.Name)
</div>
<div class="display-field">
@Html.DisplayFor(model => model.Name)
</div>
<div class="display-label">
@Html.DisplayNameFor(model => model.Email)
</div>
<div class="display-field">
@Html.DisplayFor(model => model.Email)
</div>
<div class="display-label">
@Html.DisplayNameFor(model => model.Age)
</div>
<div class="display-field">
@Html.DisplayFor(model => model.Age)
</div>
</fieldset>
<p>
@Html.ActionLink("Edit", "Edit", new { id=Model.Id }) |
@Html.ActionLink("Back to List", "Index")
</p>
Run the application and click on detail link in the user list.
Figure 1.4 Show details of single user
Operation 4: Update User Details
Create two actions in the controller, one for an existing user edit view (Get Action) and another for submitting the updated user details to the repository (Post Action). These have the same name Edit. The Get action fills in the user details on the form by the id of the user so we would pass the id to the action.
public ActionResult Edit(int id)
{
UserModel model = _repository.GetUserById(id);
return View(model);
}
[HttpPost]
public ActionResult Edit(UserModel user)
{
try
{
if (ModelState.IsValid)
{
_repository.UpdateUser(user);
return RedirectToAction("Index");
}
}
catch (DataException)
{
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
}
return View(user);
}
Now we create the view. To create the view use the following procedure:
- Right-click on Action Method Edit (GET).
- The View Name is already filled in so don't change it.
- The View Engine already selected Razor so don't change it.
- Check the checkbox "Create a strongly-typed-view" because we are creating a strongly typed view.
- Choose the Model class "UserModel" so it can be bound with the view.
- Choose "Edit" from the Scaffold template so we can do rapid development and we get the view for updating an existing user.
- Check both checkboxes "Reference script libraries" and "Use a layout or master page".
@model UserRegistration.Models.UserModel
@{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>UserModel</legend>
@Html.HiddenFor(model => model.Id)
<div class="editor-label">
@Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Email)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Email)
@Html.ValidationMessageFor(model => model.Email)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Age)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Age)
@Html.ValidationMessageFor(model => model.Age)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
Run the application and click on Edit link in the user list.
Figure 1.5 Edit User Information
You can insert new updated user information in the input field then click on the "Save" button to update the user.
Operation 5: Delete User
Create two actions in the controller, one to show the details of the user after clicking on the Delete link (Get Action) and another to Delete the user (Post Action). One is the Delete action but the other overrides the Delete Action that overrides the DeleteConfirmed method. The Get action fills in user details on the form by the id of the user then the Post action is performed on it.
public ActionResult Delete(int id, bool? saveChangesError)
{
if (saveChangesError.GetValueOrDefault())
{
ViewBag.ErrorMessage = "Unable to save changes. Try again, and if the problem persists see your system administrator.";
}
UserModel user = _repository.GetUserById(id);
return View(user);
}
[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirmed(int id)
{
try
{
UserModel user = _repository.GetUserById(id);
_repository.DeleteUser(id);
}
catch (DataException)
{
return RedirectToAction("Delete",
new System.Web.Routing.RouteValueDictionary {
{ "id", id },
{ "saveChangesError", true } });
}
return RedirectToAction("Index");
}
Now we create the view. To create the view use the following procedure:
- Right-click on Action Method Delete.
- The View Name is already filled in so don't change it.
- The View Engine already selected Razor so don't change it.
- Check the checkbox "Create a strongly-typed-view" because we are creating a strongly typed view.
- Choose the Model class "UserModel" so it can be bound with the view.
- Choose "Delete" from the Scaffold template so we can do rapid development and we get the view of the delete for the existing User.
- Check both checkboxes "Reference script libraries" and "Use a layout or master page".
@model UserRegistration.Models.UserModel
@{
ViewBag.Title = "Delete";
}
<h2>Delete</h2>
<h3>Are you sure you want to delete this?</h3>
<fieldset>
<legend>UserModel</legend>
<div class="display-label">
@Html.DisplayNameFor(model => model.Name)
</div>
<div class="display-field">
@Html.DisplayFor(model => model.Name)
</div>
<div class="display-label">
@Html.DisplayNameFor(model => model.Email)
</div>
<div class="display-field">
@Html.DisplayFor(model => model.Email)
</div>
<div class="display-label">
@Html.DisplayNameFor(model => model.Age)
</div>
<div class="display-field">
@Html.DisplayFor(model => model.Age)
</div>
</fieldset>
@using (Html.BeginForm()) {
<p>
<input type="submit" value="Delete" /> |
@Html.ActionLink("Back to List", "Index")
</p>
}
Run the application and click on Delete link in the user list.
Figure 1.6 Delete a user
Now click on the Delete button and the user will be deleted. Now the view and action are ready to perform CRUD operations.
You can download source code for this application from the zip folder.