NHibernate and ASP.NET MVC - CRUD Operations


참조 URL
  1. http://www.dotnetjalps.com/2013/09/asp-net-mvc-nhibernate-crud-getting-started.html
  2. http://www.dotnetjalps.com/2014/07/fluent-nhibernate-asp-net-mvc-crud.html

 


이 문서에 대하여

이 문서는 원본 문서를 읽고, 따라하고, 변경 또는 수정없이 인용한 부분이 있으며 주석이나 추가 설명에 대해 가감을 하였습니다. 이 문서와는 별개로 별도의 원본이 있음을 알려 드리며 원본에 대한 자세한 사항은 참조 URL에 있음을 알려 드립니다. 오역, 어색한 부분, 매끄럽지 않은 부분이 있을 경우 알려주시면 적극적으로 반영하도록 하겠습니다.





   실습 준비 사항


  • Visual Studio 2013
  • ASP.NET MVC5
  • LocalDB 11 




 NHibernate를 통해 ASP.NET MVC에서 간단한 CRUD를 해보도록 하겠다. 우선 준비 사항으로 데이터 베이스가 필요하여 아래와 같이 Employee테이블을 만들었다. '코드1'에서 관련 Query가 있으니 SQL Server Management Studio에서 실행하여 테이블을 생성할 수 있도록 하였다.



[그림1] Employee Table




CREATE TABLE [dbo].[Employee](
	[Id] [intIDENTITY(1,1NOT NULL,
	[FirstName] [nvarchar](50NULL,
	[LastName] [nvarchar](50NULL,
	[Designation] [nvarchar](50NULLON [PRIMARY]

[코드1] Create query Employee table 





 이제 준비가 되었으면 아래와 같이 웹 프로젝트를 만들어 보자.



[그림2] ASP.NET MVC template




[그림3] ASP.NET MVC Web API 선택



NHibernate 관련 DLL을 참조 하여야 한다. 참조 방법은 PM( Tools -> NuGet Package Manager -> Package Manager Console )에서 "Install-Package NHibernate"를 입력하면 참조가 된다.
( "그림4"에서는 이미 참조가 되어 있는 관계로 처음 참조하는 화면과는 다르며 예시를 하기 위함입니다. )




[그림4] Package Manager Console




NHibernate에서 사용하는 Config 파일을 Models폴더에 추가 하자. 추가할 파일명은 "Hibernate.cfg.xml"로 한다.


<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
  <session-factory>
    <property name="connection.provider">
      NHibernate.Connection.DriverConnectionProvider
    </property>
    <property name="connection.driver_class">
      NHibernate.Driver.SqlClientDriver
    </property>
    <property name="connection.connection_string">
      Server=(LocalDB)\v11.0;Integrated Security=true;AttachDbFileName=C:\Users\천호\NHibernateTest.mdf
    </property>
    <property name="dialect">
      NHibernate.Dialect.MsSql2012Dialect
    </property>
  </session-factory>
</hibernate-configuration>

[코드2] NHibernate.cfg.xml



이제 Employee 관련 모델 클래스를 만든다.


public class Employee
{
    public virtual int Id { getset; }
    public virtual string FirstName { getset; }
    public virtual string LastName { getset; }
    public virtual string Designation { getset; }
}

[코드3] Employee model class



이제 모델 클래스와 DB의 Table과 매칭시켜 주는 파일을 Models 폴더에 추가해야 한다. 파일명은 "Employee.hbm.xml"로 한다.


<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="true" assembly="NHibernateTest" namespace="NHibernateTest.Models">
  <class name="Employee" table="Employee" dynamic-update="true" >
    <cache usage="read-write"/>
    <id name="Id" column="Id" type="int">
      <generator class="native" />
    </id>
    <property name="FirstName" />
    <property name="LastName" />
    <property name="Designation" />
  </class>
</hibernate-mapping>

[코드4] Employee.hbm.xml




NHibernate을 접근하기 위한 Helper 클래스를 만든다.


public static ISession OpenSession()
{
    var configuration = new Configuration();
    // Configue 파일에 대한 정보
    var configurationPath = HttpContext.Current.Server.MapPath(@"~\Models\hibernate.cfg.xml");
    configuration.Configure(configurationPath);
 
    // 매칭 정보에 관한 파일
    var employeeConfigurationFile = HttpContext.Current.Server.MapPath(@"~\Models\Employee.hbm.xml");
            
    configuration.AddFile(employeeConfigurationFile);
    ISessionFactory sessionFactory = configuration.BuildSessionFactory();
    return sessionFactory.OpenSession();
}

[코드5] NHibernateSession Helper 클래스


 위 코드에서 MapPath를 통해 설정 정보와 매칭 정보가 있는 파일 정보를 세션 객체를 초기화 하는 작업이다. 이제 기본적인 준비 작업은 마무리가 되었으며 Controller에서 CRUD를 해보도록 하겠다.



public ActionResult Index()
{
	using (ISession session = NHibertnateSession.OpenSession())
	{
		var employees = session.Query<Employee>().ToList();
		return View(employees);
	}
}
 
public ActionResult Create()
{
	return View();
}
 
 
[HttpPost]
public ActionResult Create(Employee emplolyee)
{
	try
	{
		using (ISession session = NHibertnateSession.OpenSession())
		{
			using (ITransaction transaction = session.BeginTransaction())
			{
				session.Save(emplolyee);
				transaction.Commit();
			}
		}
 
		return RedirectToAction("Index");
	}
	catch (Exception exception)
	{
		return View();
	}
}
 
public ActionResult Edit(int id)
{
	using (ISession session = NHibertnateSession.OpenSession())
	{
		var employee = session.Get<Employee>(id);
		return View(employee);
	}
 
}
 
 
[HttpPost]
public ActionResult Edit(int idEmployee employee)
{
	try
	{
		using (ISession session = NHibertnateSession.OpenSession())
		{
			var employeetoUpdate = session.Get<Employee>(id);
 
			employeetoUpdate.Designation = employee.Designation;
			employeetoUpdate.FirstName = employee.FirstName;
			employeetoUpdate.LastName = employee.LastName;
 
			using (ITransaction transaction = session.BeginTransaction())
			{
				session.Save(employeetoUpdate);
				transaction.Commit();
			}
		}
		return RedirectToAction("Index");
	}
	catch
	{
		return View();
	}
}
 
public ActionResult Details(int id)
{
	using (ISession session = NHibertnateSession.OpenSession())
	{
		var employee = session.Get<Employee>(id);
		return View(employee);
	}
}
 
public ActionResult Delete(int id)
{
	using (ISession session = NHibertnateSession.OpenSession())
	{
		var employee = session.Get<Employee>(id);
		return View(employee);
	}
}
 
 
[HttpPost]
public ActionResult Delete(int idEmployee employee)
{
	try
	{
		using (ISession session = NHibertnateSession.OpenSession())
		{
			using (ITransaction transaction = session.BeginTransaction())
			{
				session.Delete(employee);
				transaction.Commit();
			}
		}
		return RedirectToAction("Index");
	}
	catch (Exception exception)
	{
		return View();
	}
}

[코드6] EmployeeController




이제 View 페이지를 만든다.


@model NHibernateTest.Models.Employee
 
@{
    ViewBag.Title = "Create";
}
 
<h2>Create</h2>
 
 
@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()
    
    <div class="form-horizontal">
        <h4>Employee</h4>
        <hr />
        @Html.ValidationSummary(true)
 
        <div class="form-group">
            @Html.LabelFor(model => model.FirstNamenew { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.FirstName)
                @Html.ValidationMessageFor(model => model.FirstName)
            </div>
        </div>
 
        <div class="form-group">
            @Html.LabelFor(model => model.LastNamenew { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.LastName)
                @Html.ValidationMessageFor(model => model.LastName)
            </div>
        </div>
 
        <div class="form-group">
            @Html.LabelFor(model => model.Designationnew { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Designation)
                @Html.ValidationMessageFor(model => model.Designation)
            </div>
        </div>
 
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}
 
<div>
    @Html.ActionLink("Back to List""Index")
</div>
 
@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

[코드7] Create




@model IEnumerable<NHibernateTest.Models.Employee>
 
@{
    ViewBag.Title = "Index";
}
 
<h2>Index</h2>
 
<p>
    @Html.ActionLink("Create New""Create")
</p>
<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.FirstName)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.LastName)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Designation)
        </th>
        <th></th>
    </tr>
 
@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.FirstName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.LastName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Designation)
        </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>

[코드8] Index




@model NHibernateTest.Models.Employee
 
@{
    ViewBag.Title = "Edit";
}
 
<h2>Edit</h2>
 
 
@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    
    <div class="form-horizontal">
        <h4>Employee</h4>
        <hr />
        @Html.ValidationSummary(true)
        @Html.HiddenFor(model => model.Id)
 
        <div class="form-group">
            @Html.LabelFor(model => model.FirstNamenew { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.FirstName)
                @Html.ValidationMessageFor(model => model.FirstName)
            </div>
        </div>
 
        <div class="form-group">
            @Html.LabelFor(model => model.LastNamenew { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.LastName)
                @Html.ValidationMessageFor(model => model.LastName)
            </div>
        </div>
 
        <div class="form-group">
            @Html.LabelFor(model => model.Designationnew { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Designation)
                @Html.ValidationMessageFor(model => model.Designation)
            </div>
        </div>
 
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>
    </div>
}
 
<div>
    @Html.ActionLink("Back to List""Index")
</div>
 
@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

[코드9] Edit




@model NHibernateTest.Models.Employee
 
@{
    ViewBag.Title = "Details";
}
 
<h2>Details</h2>
 
<div>
    <h4>Employee</h4>
	<hr />
    <dl class="dl-horizontal">
        <dt>
            @Html.DisplayNameFor(model => model.FirstName)
        </dt>
 
        <dd>
            @Html.DisplayFor(model => model.FirstName)
        </dd>
 
        <dt>
            @Html.DisplayNameFor(model => model.LastName)
        </dt>
 
        <dd>
            @Html.DisplayFor(model => model.LastName)
        </dd>
 
        <dt>
            @Html.DisplayNameFor(model => model.Designation)
        </dt>
 
        <dd>
            @Html.DisplayFor(model => model.Designation)
        </dd>
 
    </dl>
</div>
<p>
    @Html.ActionLink("Edit""Edit"new { id = Model.Id }) |
    @Html.ActionLink("Back to List""Index")
</p>

[코드10] Details




@model NHibernateTest.Models.Employee
 
@{
    ViewBag.Title = "Delete";
}
 
<h2>Delete</h2>
 
<h3>Are you sure you want to delete this?</h3>
<div>
    <h4>Employee</h4>
    <hr />
    <dl class="dl-horizontal">
        <dt>
            @Html.DisplayNameFor(model => model.FirstName)
        </dt>
 
        <dd>
            @Html.DisplayFor(model => model.FirstName)
        </dd>
 
        <dt>
            @Html.DisplayNameFor(model => model.LastName)
        </dt>
 
        <dd>
            @Html.DisplayFor(model => model.LastName)
        </dd>
 
        <dt>
            @Html.DisplayNameFor(model => model.Designation)
        </dt>
 
        <dd>
            @Html.DisplayFor(model => model.Designation)
        </dd>
 
    </dl>
 
    @using (Html.BeginForm()) {
        @Html.AntiForgeryToken()
 
        <div class="form-actions no-color">
            <input type="submit" value="Delete" class="btn btn-default" /> |
            @Html.ActionLink("Back to List""Index")
        </div>
    }
</div>

[코드11] Delete




이제 모든 준비가 되었으니 확인해 보도록 한다.



이 프로젝테에서 사용하는 DB는 LocalDB V11 을 사용하였다. Hibernate.cfg.xml 파일에서  "AttachDbFileName" 부분을 자신의 환경에 맞게 수정해야 한다.




[그림2] List





[그림3] Edit





Source Download

NHibernateTest.zip





+ Recent posts