-
Notifications
You must be signed in to change notification settings - Fork 0
4. CRUD
After the actions described above, we come to the most interesting part – code writing implementing the CRUD (create, read, update, delete) functionality of an application. To begin this process, create an entity class that will map to the DB. In our case, this is Human.cs that we add to the Example.Domain -> Persistences folder.
``` namespace Example.Domain { #region << Using >>using System;
using Incoding.Data;
#endregion
public class Human : IncEntityBase
{
#region Properties
public virtual DateTime Birthday { get; set; }
public virtual string FirstName { get; set; }
public new virtual string Id { get; set; }
public virtual string LastName { get; set; }
public virtual Sex Sex { get; set; }
#endregion
#region Nested Classes
public class Map : NHibernateEntityMap<Human>
{
#region Constructors
protected Map()
{
IdGenerateByGuid(r => r.Id);
MapEscaping(r => r.FirstName);
MapEscaping(r => r.LastName);
MapEscaping(r => r.Birthday);
MapEscaping(r => r.Sex);
}
#endregion
}
#endregion
}
public enum Sex
{
Male = 1,
Female = 2
}
}
<p>Our class contains several fields where we will write data and Nested Class Map.</p>
<p>We can now add commands and queries, which are responsible for realization of the CRUD operations. The first command will be responsible for adding a new or change an existing record of the <em>Human</em> type. The command is quite simple: we either get an entity on a Repository using the key (Id) or, if no entity exist, we create a new one. Both of these entities get the values specified in the properties of the <em>AddOrEditHumanCommand</em> class. Add <strong>Example.Domain -> Operations -> AddOrEditHumanCommand.cs to the project.</strong></p>
<h6>AddOrEditHumanCommand.cs</h6>
namespace Example.Domain { #region << Using >>
using System;
using FluentValidation;
using Incoding.CQRS;
using Incoding.Extensions;
#endregion
public class AddOrEditHumanCommand : CommandBase
{
#region Properties
public DateTime BirthDay { get; set; }
public string FirstName { get; set; }
public string Id { get; set; }
public string LastName { get; set; }
public Sex Sex { get; set; }
#endregion
public override void Execute()
{
var human = Repository.GetById<Human>(Id) ?? new Human();
human.FirstName = FirstName;
human.LastName = LastName;
human.Birthday = BirthDay;
human.Sex = Sex;
Repository.SaveOrUpdate(human);
}
}
}
<p>The Read command is the second part of the CRUD. This is a request for reading entities from the DB. Add the file <strong>Example.Domain -> Operations -> GetPeopleQuery.cs</strong>.</p>
<h6>GetPeopleQuery.cs</h6>
namespace Example.Domain { #region << Using >>
using System.Collections.Generic;
using System.Linq;
using Incoding.CQRS;
#endregion
public class GetPeopleQuery : QueryBase<List<GetPeopleQuery.Response>>
{
#region Properties
public string Keyword { get; set; }
#endregion
#region Nested Classes
public class Response
{
#region Properties
public string Birthday { get; set; }
public string FirstName { get; set; }
public string Id { get; set; }
public string LastName { get; set; }
public string Sex { get; set; }
#endregion
}
#endregion
protected override List<Response> ExecuteResult()
{
return Repository.Query<Human>()
.Select(human => new Response
{
Id = human.Id,
Birthday = human.Birthday.ToShortDateString(),
FirstName = human.FirstName,
LastName = human.LastName,
Sex = human.Sex.ToString()
}).ToList();
}
}
}
<p>The Delete command is the remaining part of the CRUD. The command deletes records from the DB using the key (Id). Add the file <strong>Example.Domain -> Operations -> DeleteHumanCommand.cs</strong>.</p>
<h6>DeleteHumanCommand.cs</h6>
namespace Example.Domain { #region << Using >>
using Incoding.CQRS;
#endregion
public class DeleteHumanCommand : CommandBase
{
#region Properties
public string HumanId { get; set; }
#endregion
public override void Execute()
{
Repository.Delete<Human>(HumanId);
}
}
}
<p>In order to populate the DB with initial data, add the file <strong>Example.Domain -> InitPeople.cs </strong>that is derived from the <em>ISetUP</em> interface.</p>
<h6 style="text-align: justify;">ISetup</h6>
using System;
namespace Incoding.CQRS { public interface ISetUp : IDisposable { int GetOrder();
void Execute();
} }
<p>All the class instances from the <em>ISetUp</em> are registered with IoC in the Bootstrapper.cs (see Introduction) and run (<em>public void Execute()</em>) in order (<em>public int GetOrder()</em>).</p>
<h6>InitPeople.cs</h6>
namespace Example.Domain { #region << Using >>
using System;
using Incoding.Block.IoC;
using Incoding.CQRS;
using NHibernate.Util;
#endregion
public class InitPeople : ISetUp
{
public void Dispose() { }
public int GetOrder()
{
return 0;
}
public void Execute()
{
var dispatcher = IoCFactory.Instance.TryResolve<IDispatcher>();
if (dispatcher.Query(new GetEntitiesQuery<Human>()).Any())
return;
dispatcher.Push(new AddOrEditHumanCommand
{
FirstName = "Hellen",
LastName = "Jonson",
BirthDay = Convert.ToDateTime("06/05/1985"),
Sex = Sex.Female
});
dispatcher.Push(new AddOrEditHumanCommand
{
FirstName = "John",
LastName = "Carlson",
BirthDay = Convert.ToDateTime("06/07/1985"),
Sex = Sex.Male
});
}
}
}
<p>The back-end implementation of the CRUD is ready. Now it is time to add a user code. As in the case of the back end, we begin the implementation with creating/editing a record. Add the file<strong> Example.UI -> Views -> Home -> AddOrEditHuman.cshtml.</strong></p>
<h6>AddOrEditHuman.cshtml</h6>
@using Example.Domain @using Incoding.MetaLanguageContrib @using Incoding.MvcContrib @model Example.Domain.AddOrEditHumanCommand @using (Html.When(JqueryBind.Submit) .PreventDefault() .Submit() .OnSuccess(dsl => { dsl.WithId("PeopleTable").Core().Trigger.Incoding(); dsl.WithId("dialog").JqueryUI().Dialog.Close(); }) .OnError(dsl => dsl.Self().Core().Form.Validation.Refresh()) .AsHtmlAttributes(new { action = Url.Dispatcher().Push(new AddOrEditHumanCommand()), enctype = "multipart/form-data", method = "POST" }) .ToBeginTag(Html, HtmlTag.Form)) {
@Html.ForGroup(r => r.LastName).TextBox(control => control.Label.Name = "Last name")
@Html.ForGroup(r => r.BirthDay).TextBox(control => control.Label.Name = "Birthday")
@Html.ForGroup(r => r.Sex).DropDown(control => control.Input.Data = typeof(Sex).ToSelectList())
<div>
<input type="submit" value="Save"/>
@(Html.When(JqueryBind.Click)
.PreventDefault()
.StopPropagation()
.Direct()
.OnSuccess(dsl => { dsl.WithId("dialog").JqueryUI().Dialog.Close(); })
.AsHtmlAttributes()
.ToButton("Cancel"))
</div>
}
<p>The IML-code creates the standard HTML form and works with <em>AddOrEditHumanCommand</em>, sending the appropriate Ajax query to the server.</p>
<p>Then comes the template for data loading through the GetPeopleQuery. There is a description of the table that will be responsible not only for data output, but also for record deletion and editing: add the file <strong>Example.UI -> Views -> Home -> HumanTmpl.cshtml.</strong></p>
<h6>HumanTmpl.cshtml</h6>
@using Example.Domain @using Incoding.MetaLanguageContrib @using Incoding.MvcContrib @{ using (var template = Html.Incoding().Template<GetPeopleQuery.Response>()) {
@using (var each = template.ForEach()) {First name | Last name | Birthday | Sex | |
---|---|---|---|---|
@each.For(r => r.FirstName) | @each.For(r => r.LastName) | @each.For(r => r.Birthday) | @each.For(r => r.Sex) |
@(Html.When(JqueryBind.Click)
.AjaxGet(Url.Dispatcher().Model(new
{
Id = each.For(r => r.Id),
FirstName = each.For(r => r.FirstName),
LastName = each.For(r => r.LastName),
BirthDay = each.For(r => r.Birthday),
Sex = each.For(r => r.Sex)
})
.AsView("~/Views/Home/AddOrEditHuman.cshtml"))
.OnSuccess(dsl => dsl.WithId("dialog").Behaviors(inDsl =>
{
inDsl.Core().Insert.Html();
inDsl.JqueryUI().Dialog.Open(option =>
{
option.Resizable = false;
option.Title = "Edit human";
});
}))
.AsHtmlAttributes()
.ToButton("Edit"))
}
@using Example.Domain @using Incoding.MetaLanguageContrib @using Incoding.MvcContrib @{ Layout = "~/Views/Shared/_Layout.cshtml"; } @(Html.When(JqueryBind.InitIncoding) .AjaxGet(Url.Dispatcher().Query(new GetPeopleQuery()).AsJson()) .OnSuccess(dsl => dsl.Self().Core().Insert.WithTemplateByUrl(Url.Dispatcher().AsView("~/Views/Home/HumanTmpl.cshtml")).Html()) .AsHtmlAttributes(new { id = "PeopleTable" }) .ToDiv()) @(Html.When(JqueryBind.Click) .AjaxGet(Url.Dispatcher().AsView("~/Views/Home/AddOrEditHuman.cshtml")) .OnSuccess(dsl => dsl.WithId("dialog").Behaviors(inDsl => { inDsl.Core().Insert.Html(); inDsl.JqueryUI().Dialog.Open(option => { option.Resizable = false; option.Title = "Add human"; }); })) .AsHtmlAttributes() .ToButton("Add new human"))
#region Nested Classes public class Validator : AbstractValidator { #region Constructors
} #endregion
@Html.ForGroup()
@Html.ValidationMessageFor()
|