<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Đào Hải Nam</title>
	<atom:link href="http://namdh.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://namdh.wordpress.com</link>
	<description>Luôn hạnh phúc vì vẫn còn nhiều ước mơ chưa đạt được</description>
	<lastBuildDate>Sat, 28 Jan 2012 19:33:55 +0000</lastBuildDate>
	<language>vi</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='namdh.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Đào Hải Nam</title>
		<link>http://namdh.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://namdh.wordpress.com/osd.xml" title="Đào Hải Nam" />
	<atom:link rel='hub' href='http://namdh.wordpress.com/?pushpress=hub'/>
		<item>
		<title>NB1001: Các ví dụ, bài tập về nhà, bài mẫu&#8230; tháng 11</title>
		<link>http://namdh.wordpress.com/2011/11/28/nb1001-cac-vi-d%e1%bb%a5-bai-t%e1%ba%adp-v%e1%bb%81-nha-bai-m%e1%ba%abu-thang-11/</link>
		<comments>http://namdh.wordpress.com/2011/11/28/nb1001-cac-vi-d%e1%bb%a5-bai-t%e1%ba%adp-v%e1%bb%81-nha-bai-m%e1%ba%abu-thang-11/#comments</comments>
		<pubDate>Mon, 28 Nov 2011 10:43:28 +0000</pubDate>
		<dc:creator>namdh</dc:creator>
				<category><![CDATA[Training]]></category>
		<category><![CDATA[NB1]]></category>

		<guid isPermaLink="false">http://namdh.wordpress.com/?p=1625</guid>
		<description><![CDATA[Chào các bạn đang học NB1001, sau đây là code của các bài tập, ví dụ, code mẫu&#8230; của tháng 11. Trong đây chỉ bao gồm các project VS2010, không bao gồm các bài lý thuyết. - Object Diagram: vẽ các hình chữ nhật và tam giác, cho phép kéo các đối tượng lên vị [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=namdh.wordpress.com&amp;blog=4017103&amp;post=1625&amp;subd=namdh&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Chào các bạn đang học NB1001, sau đây là code của các bài tập, ví dụ, code mẫu&#8230; của tháng 11. Trong đây chỉ bao gồm các project VS2010, không bao gồm các bài lý thuyết.</p>
<p>- Object Diagram: vẽ các hình chữ nhật và tam giác, cho phép kéo các đối tượng lên vị trí bất kỳ trên màn hình, double click để đổi màu.</p>
<p style="text-align:center;"><a href="http://namdh.files.wordpress.com/2011/11/nb1_object_diagram.png"><img class="aligncenter  wp-image-1626" style="border:0 none;" title="nb1_object_diagram" src="http://namdh.files.wordpress.com/2011/11/nb1_object_diagram.png?w=700&#038;h=390" alt="" width="700" height="390" /></a></p>
<p>- Chương trình tạo số ngẫu nhiên: là bài thay thế cho chương trình Mine Sweeper.</p>
<p style="text-align:center;"><a href="http://namdh.files.wordpress.com/2011/11/nb1_random_number.png"><img class="aligncenter size-full wp-image-1627" style="border:0 none;" title="nb1_random_number" src="http://namdh.files.wordpress.com/2011/11/nb1_random_number.png?w=700" alt=""   /></a></p>
<p>- Bài sắp xếp:biểu diễn các thuật toán sắp xếp một cách trực quan.</p>
<p style="text-align:center;"><a href="http://namdh.files.wordpress.com/2011/11/nb1_sort_demo.png"><img class="aligncenter size-full wp-image-1628" style="border:0 none;" title="nb1_sort_demo" src="http://namdh.files.wordpress.com/2011/11/nb1_sort_demo.png?w=700&#038;h=475" alt="" width="700" height="475" /></a></p>
<p>Bài Gỡ Mìn các bạn có thể thao khảo: <a href="http://namdh.wordpress.com/2008/07/27/ch%C6%B0%C6%A1ng-trinh-android-th%E1%BB%A9-hai-minesweeper/">http://namdh.wordpress.com/2008/07/27/ch%C6%B0%C6%A1ng-trinh-android-th%E1%BB%A9-hai-minesweeper/</a>.</p>
<p>Chương trình thực thi và Mã nguồn: <a href="http://www.mediafire.com/?ime71m4tu0ust">http://www.mediafire.com/?ime71m4tu0ust</a> (bao gồm cả chương trình gỡ mìn trên Android)</p>
<p>Chú ý là bài Sort Demo bản exe là đầy đủ, còn mã nguồn đã bị xóa mất 3 phương thức sắp xếp: insertion, selection, quick.</p>
<br /> Tagged: <a href='http://namdh.wordpress.com/tag/nb1/'>NB1</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/namdh.wordpress.com/1625/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/namdh.wordpress.com/1625/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/namdh.wordpress.com/1625/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/namdh.wordpress.com/1625/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/namdh.wordpress.com/1625/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/namdh.wordpress.com/1625/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/namdh.wordpress.com/1625/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/namdh.wordpress.com/1625/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/namdh.wordpress.com/1625/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/namdh.wordpress.com/1625/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/namdh.wordpress.com/1625/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/namdh.wordpress.com/1625/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/namdh.wordpress.com/1625/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/namdh.wordpress.com/1625/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=namdh.wordpress.com&amp;blog=4017103&amp;post=1625&amp;subd=namdh&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://namdh.wordpress.com/2011/11/28/nb1001-cac-vi-d%e1%bb%a5-bai-t%e1%ba%adp-v%e1%bb%81-nha-bai-m%e1%ba%abu-thang-11/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">namdh</media:title>
		</media:content>

		<media:content url="http://namdh.files.wordpress.com/2011/11/nb1_object_diagram.png" medium="image">
			<media:title type="html">nb1_object_diagram</media:title>
		</media:content>

		<media:content url="http://namdh.files.wordpress.com/2011/11/nb1_random_number.png" medium="image">
			<media:title type="html">nb1_random_number</media:title>
		</media:content>

		<media:content url="http://namdh.files.wordpress.com/2011/11/nb1_sort_demo.png" medium="image">
			<media:title type="html">nb1_sort_demo</media:title>
		</media:content>
	</item>
		<item>
		<title>Một vài hình ảnh lớp NB1001</title>
		<link>http://namdh.wordpress.com/2011/11/14/nb1001-pictures/</link>
		<comments>http://namdh.wordpress.com/2011/11/14/nb1001-pictures/#comments</comments>
		<pubDate>Mon, 14 Nov 2011 09:59:18 +0000</pubDate>
		<dc:creator>namdh</dc:creator>
				<category><![CDATA[Training]]></category>
		<category><![CDATA[NB1]]></category>

		<guid isPermaLink="false">http://namdh.wordpress.com/?p=1615</guid>
		<description><![CDATA[Tagged: NB1<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=namdh.wordpress.com&amp;blog=4017103&amp;post=1615&amp;subd=namdh&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p style="text-align:center;"><a href="http://namdh.files.wordpress.com/2011/11/imag0238_resized.jpg"><img class="aligncenter size-full wp-image-1617" style="border:0 none;" title="IMAG0238_resized" src="http://namdh.files.wordpress.com/2011/11/imag0238_resized.jpg?w=700&#038;h=418" alt="" width="700" height="418" /></a></p>
<p style="text-align:center;"><a href="http://namdh.files.wordpress.com/2011/11/imag0239_resized.jpg"><img class="aligncenter size-full wp-image-1618" style="border:0 none;" title="IMAG0239_resized" src="http://namdh.files.wordpress.com/2011/11/imag0239_resized.jpg?w=700&#038;h=418" alt="" width="700" height="418" /></a></p>
<p style="text-align:center;"><a href="http://namdh.files.wordpress.com/2011/11/imag0240_resized.jpg"><img class="aligncenter size-full wp-image-1619" style="border:0 none;" title="IMAG0240_resized" src="http://namdh.files.wordpress.com/2011/11/imag0240_resized.jpg?w=700&#038;h=418" alt="" width="700" height="418" /></a></p>
<p style="text-align:center;"><a href="http://namdh.files.wordpress.com/2011/11/imag0242_resized.jpg"><img class="aligncenter size-full wp-image-1620" style="border:0 none;" title="IMAG0242_resized" src="http://namdh.files.wordpress.com/2011/11/imag0242_resized.jpg?w=700&#038;h=418" alt="" width="700" height="418" /></a></p>
<p style="text-align:center;"><a href="http://namdh.files.wordpress.com/2011/11/imag0244_resized.jpg"><img class="aligncenter size-full wp-image-1621" style="border:0 none;" title="IMAG0244_resized" src="http://namdh.files.wordpress.com/2011/11/imag0244_resized.jpg?w=700&#038;h=418" alt="" width="700" height="418" /></a></p>
<p style="text-align:center;"><a href="http://namdh.files.wordpress.com/2011/11/imag0248_resized.jpg"><img class="aligncenter size-full wp-image-1622" style="border:0 none;" title="IMAG0248_resized" src="http://namdh.files.wordpress.com/2011/11/imag0248_resized.jpg?w=700&#038;h=418" alt="" width="700" height="418" /></a></p>
<br /> Tagged: <a href='http://namdh.wordpress.com/tag/nb1/'>NB1</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/namdh.wordpress.com/1615/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/namdh.wordpress.com/1615/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/namdh.wordpress.com/1615/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/namdh.wordpress.com/1615/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/namdh.wordpress.com/1615/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/namdh.wordpress.com/1615/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/namdh.wordpress.com/1615/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/namdh.wordpress.com/1615/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/namdh.wordpress.com/1615/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/namdh.wordpress.com/1615/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/namdh.wordpress.com/1615/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/namdh.wordpress.com/1615/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/namdh.wordpress.com/1615/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/namdh.wordpress.com/1615/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=namdh.wordpress.com&amp;blog=4017103&amp;post=1615&amp;subd=namdh&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://namdh.wordpress.com/2011/11/14/nb1001-pictures/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">namdh</media:title>
		</media:content>

		<media:content url="http://namdh.files.wordpress.com/2011/11/imag0238_resized.jpg" medium="image">
			<media:title type="html">IMAG0238_resized</media:title>
		</media:content>

		<media:content url="http://namdh.files.wordpress.com/2011/11/imag0239_resized.jpg" medium="image">
			<media:title type="html">IMAG0239_resized</media:title>
		</media:content>

		<media:content url="http://namdh.files.wordpress.com/2011/11/imag0240_resized.jpg" medium="image">
			<media:title type="html">IMAG0240_resized</media:title>
		</media:content>

		<media:content url="http://namdh.files.wordpress.com/2011/11/imag0242_resized.jpg" medium="image">
			<media:title type="html">IMAG0242_resized</media:title>
		</media:content>

		<media:content url="http://namdh.files.wordpress.com/2011/11/imag0244_resized.jpg" medium="image">
			<media:title type="html">IMAG0244_resized</media:title>
		</media:content>

		<media:content url="http://namdh.files.wordpress.com/2011/11/imag0248_resized.jpg" medium="image">
			<media:title type="html">IMAG0248_resized</media:title>
		</media:content>
	</item>
		<item>
		<title>Steve Jobs đã ra đi</title>
		<link>http://namdh.wordpress.com/2011/10/06/steve-jobs-da-ra-di/</link>
		<comments>http://namdh.wordpress.com/2011/10/06/steve-jobs-da-ra-di/#comments</comments>
		<pubDate>Thu, 06 Oct 2011 01:20:37 +0000</pubDate>
		<dc:creator>namdh</dc:creator>
				<category><![CDATA[Không phân loại]]></category>

		<guid isPermaLink="false">http://namdh.wordpress.com/?p=1601</guid>
		<description><![CDATA[Vậy là thế giới vừa mất đi một thiên tài, một người mang đến sự sáng tạo và tầm nhìn trong thế giới công nghệ.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=namdh.wordpress.com&amp;blog=4017103&amp;post=1601&amp;subd=namdh&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p style="text-align:center;"><a href="http://namdh.files.wordpress.com/2011/10/t_hero.png"><img class="aligncenter size-full wp-image-1603" style="border:0 none;" title="Steve Jobs" src="http://namdh.files.wordpress.com/2011/10/t_hero.png?w=700&#038;h=638" alt="" width="700" height="638" /></a></p>
<p>Vậy là thế giới vừa mất đi một thiên tài, một người mang đến sự sáng tạo và tầm nhìn trong thế giới công nghệ.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/namdh.wordpress.com/1601/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/namdh.wordpress.com/1601/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/namdh.wordpress.com/1601/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/namdh.wordpress.com/1601/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/namdh.wordpress.com/1601/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/namdh.wordpress.com/1601/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/namdh.wordpress.com/1601/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/namdh.wordpress.com/1601/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/namdh.wordpress.com/1601/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/namdh.wordpress.com/1601/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/namdh.wordpress.com/1601/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/namdh.wordpress.com/1601/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/namdh.wordpress.com/1601/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/namdh.wordpress.com/1601/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=namdh.wordpress.com&amp;blog=4017103&amp;post=1601&amp;subd=namdh&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://namdh.wordpress.com/2011/10/06/steve-jobs-da-ra-di/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">namdh</media:title>
		</media:content>

		<media:content url="http://namdh.files.wordpress.com/2011/10/t_hero.png" medium="image">
			<media:title type="html">Steve Jobs</media:title>
		</media:content>
	</item>
		<item>
		<title>Best Practices for ASP.NET MVC: Controller (Phần 3)</title>
		<link>http://namdh.wordpress.com/2011/10/05/best-practices-for-asp-net-mvc-controller/</link>
		<comments>http://namdh.wordpress.com/2011/10/05/best-practices-for-asp-net-mvc-controller/#comments</comments>
		<pubDate>Wed, 05 Oct 2011 02:44:54 +0000</pubDate>
		<dc:creator>namdh</dc:creator>
				<category><![CDATA[Microsoft .NET]]></category>
		<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[Best Practices for ASP.NET MVC]]></category>

		<guid isPermaLink="false">http://namdh.wordpress.com/?p=1595</guid>
		<description><![CDATA[[Bài viết này dựa trên một tài liệu của tác giả Ben Grover (một nhà phát triển cấp cao từ Microsoft). Chúng tôi dự định sẽ đưa những thông tin này vào phần tài liệu MVC 3 trên trang MSDN. Chúng tôi hi vọng được nghe những phản hổi  và mong chờ bất kỳ góp [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=namdh.wordpress.com&amp;blog=4017103&amp;post=1595&amp;subd=namdh&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><span style="color:#ff0000;">[Bài viết này dựa trên một tài liệu của tác giả Ben Grover (một nhà phát triển cấp cao từ Microsoft). Chúng tôi dự định sẽ đưa những thông tin này vào phần tài liệu MVC 3 trên trang MSDN. Chúng tôi hi vọng được nghe những phản hổi  và mong chờ bất kỳ góp ý nào từ phía các bạn]</span></p>
<p>Bài viết này giới thiệu một tập các hướng dẫn lập trình nhắm đến các lập trình viên ASP.NET MVC. Tất nhiên, bạn, với tư cách là nhà phát triển sẽ vẫn là người quyết định cuối cùng trong việc chọn hướng dẫn nào phù hợp nhất.</p>
<ul>
<li><a href="http://namdh.wordpress.com/2011/09/27/best-practices-for-asp-net-mvc-model/">Phần 1: Model</a></li>
<li><a href="http://namdh.wordpress.com/2011/09/27/best-practices-for-asp-net-mvc-view/">Phần 2: View</a></li>
<li><a href="http://namdh.wordpress.com/2011/10/05/best-practices-for-asp-net-mvc-controller/">Phần 3: Controller</a></li>
</ul>
<p><span id="more-1595"></span></p>
<h1>Các khuyến nghị trong việc tạo Controller</h1>
<p>Controller (với một action method cụ thể) được gọi bởi hệ thống định tuyến (routing system) bằng cách dựa trên dạng của URL. Controller nhận vào input từ routing system, trong đó bao gồm cả các thành phần trong HTTP request context (session, cookies, browser, &#8230;).</p>
<h2>Nên: dùng model binding thay vì tự xử lý request.</h2>
<p>ASP.NET trừu tượng hóa nhiều lệnh liên quan đến việc tạo lại đối tượng bằng cách dùng model binding. Model binding là một kỹ thuật trong đó dữ liệu từ request sẽ được tự động trích xuất để tạo nên kiểu dữ liệu đầu vào cho phương thức action.</p>
<p>Ví dụ sau cho thấy một lớp Seller định nghĩa dữ liệu có thể dùng để gửi từ một form đăng ký người bán (seller):</p>
<pre>public class Seller
{
    public Int64 ID { get; set; }
    public string Name { get; set; }
    public string Phone { get; set; }
    public string Address { get; set; }
}</pre>
<p>Form đăng ký sẽ được chứa trong view Register và có dạng sau:</p>
<pre>&lt;% using (Html.BeginForm()) { %&gt;
  &lt;legend&gt;Account Information&lt;/legend&gt;
  &lt;p&gt;
      &lt;%= Html.TextBox("Name") %&gt;
  &lt;/p&gt;
  &lt;p&gt;
      &lt;%= Html.TextBox("Phone") %&gt;
  &lt;/p&gt;
  &lt;p&gt;
      &lt;%= Html.TextBox("Address") %&gt;
  &lt;/p&gt;
  &lt;p&gt;
      &lt;input value="Register" type="submit" /&gt;
  &lt;/p&gt;
&lt;% } %&gt;</pre>
<p>Controller có thể đăng ký một phương thức action để cung cấp model binding như dưới đây:</p>
<pre>public ActionResult Register([Bind(Exclude="ID")] Seller newSeller)
{
   ...
}</pre>
<p>Default model binder sẽ dò từng thuộc tính trong lớp cho trước theo thứ tự sau (lấy ví dụ thuộc tính Name):</p>
<ol>
<li><code>Request.Form["Name"], nếu có<br />
</code></li>
<li><code>RouteData.Values["Name"], nếu có<br />
</code></li>
<li><code>Request.QueryString["Namel"], nếu có<br />
</code></li>
<li>Ngược lại, <code>null</code></li>
</ol>
<p>Như bạn có thể thấy từ phương thức action Register, có một số attribute bạn có thể đặt cho đối tượng tham số sẽ được gọi ởi model binder mặc nhiên.</p>
<p>Hệ thống model binding cũng sẽ chạy các phép kiểm tra được áp dụng cho đối tượng dữ liệu, kiểu như các annotation attibute (Xem thêm &#8220;<strong>Nên: đặt tất cả các quy tắc xác định giá trị hợp lệ của dữ liệu bên trong model.</strong>&#8220;).</p>
<p>Hệ thống model binding có rất nhiều cơ chế mở rộng cho phép chúng ta tùy biến tất cả các thao tác tạo, đưa dữ liệu vào đối tượng hay kiểm tra dữ liệu của nó.</p>
<h2>Nên: Chỉ ra tên view cụ thể trong phương thức action.</h2>
<p>Sau khi bạn đã thiết lập đầy đủ các giá trị để tạo mã HTML trong phương thức action, bạn sẽ trả về ViewResult hoặc PartialViewResult. Nếu bạn không truyền tên view, tên file view sẽ được chọn tự động dựa trên tên phương thức action. Ví dụ, cho một controller có tên Products với một phương thức action có tên List. Bạn có thể gọi &#8220;return View()&#8221; từ bên trong phương thức List mà không cần bất kỳ tham số nào. MVC Framework sẽ tìm kiếm một view có tên <em>/Views/Products/List.aspx</em>. Nếu không tìm thấy, sẽ tìm tiếp <em>/Views/Products/List.ascx</em>. Nếu vẫn không tìm thấy, nó sẽ thử tìm <em>/Views/Shared/List.aspx</em> và rồi <em>/Views/Shared/List.ascx</em>. Do vậy, bạn có thể dùng <em>/Views/Shared</em> cho các view có thể được dùng bởi nhiều controller khác nhau.</p>
<p>Để tránh tranh chấp, tốt nhất bạn nên chỉ rõ tên view, kiểu như &#8220;return View(&#8220;<em>một tên cụ thể nào đó&#8221;)&#8221;</em>, trong phương thức action. Điều này cho phép bạn gọi List từ các action khác nhau, và framework sẽ không phải đi tìm các view khác nhau.</p>
<h2>Chỉ rõ Post/Redirect/Get (PRG) khi gửi form.</h2>
<p>Căn cứ theo định nghĩa của HTTP POST và GET:</p>
<ul>
<li>HTTP GET được dùng cho dữ liệu không dùng để thay đổi mô hình dư liệu.</li>
<li>HTTP POST được dùng cho dữ liệu để thay đổi mô hình dư liệu.</li>
</ul>
<p>Cho là các định nghĩa này đã phân định rõ ràng, khi nhận dữ liệu từ form trong phương thức action, bạn có thể trả về RedirectToAction(&lt;actionName&gt;), điều này sẽ tạo ra một mã HTTP 302 (temporary redirect) và tạo lại một lời gọi GET đến &lt;actionName&gt;. Đây chính là mẫu thiết kế Post-Redirect-Get.</p>
<p>Do vậy, đừng dùng HTTP GET để gửi dữ liệu trong form, vì nó vi phạm mục đích của GET.</p>
<p>Ví dụ, trong lược đồ dưới đây, với standard post back, bạn dùng GET và POST trên cùng một URL (create.aspx). Đây sẽ là vấn đề nếu người dùng không chịu chờ cho đến khi việc post dữ liệu hoàn thành. Nếu họ nhấn nút refresh, sẽ có thể xảy ra việc dữ liệu bị gửi lên thêm một lần nữa. Bạn có thể giải quyết vấn đề này trong MVC bằng cách dùng mẫu Post-Redirect-Get.</p>
<p><a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-07-69-metablogapi/0652.PRG_5F00_pattern_5F00_2.png"><img title="PRG_pattern" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-07-69-metablogapi/0245.PRG_5F00_pattern_5F00_thumb.png" alt="PRG_pattern" width="473" height="272" border="0" /></a></p>
<p>Tuy nhiên, phương pháp này có thể làm giảm hiệu năng phía client, vì lệnh redirect sẽ tạo ra thêm request về phía server, điều này phải được đem ra cân nhắc với tính khả dụng khi quyết định chọn lựa mô hình.</p>
<h2>Nên: xử lý HandleUnknowAction và HandleError.</h2>
<p>Giá trị trả về mặc nhiên cho một thao tác không xác định được là 404 (Not Found). Nếu bạn override lại <strong>HandleUnknownAction</strong> trong một controller, bạn có thể đưa ra view mặc nhiên mỗi khi xảy ra lỗi này (404). Thêm nữa, nên đặt thuộc tính HandleError trên một action hay một controller và bạn có thể cung cấp một trang thông báo lỗi chuẩn nếu có exception xảy ra.</p>
<h1></h1>
<br /> Tagged: <a href='http://namdh.wordpress.com/tag/asp-net-mvc/'>ASP.NET MVC</a>, <a href='http://namdh.wordpress.com/tag/best-practices-for-asp-net-mvc/'>Best Practices for ASP.NET MVC</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/namdh.wordpress.com/1595/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/namdh.wordpress.com/1595/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/namdh.wordpress.com/1595/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/namdh.wordpress.com/1595/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/namdh.wordpress.com/1595/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/namdh.wordpress.com/1595/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/namdh.wordpress.com/1595/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/namdh.wordpress.com/1595/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/namdh.wordpress.com/1595/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/namdh.wordpress.com/1595/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/namdh.wordpress.com/1595/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/namdh.wordpress.com/1595/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/namdh.wordpress.com/1595/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/namdh.wordpress.com/1595/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=namdh.wordpress.com&amp;blog=4017103&amp;post=1595&amp;subd=namdh&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://namdh.wordpress.com/2011/10/05/best-practices-for-asp-net-mvc-controller/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">namdh</media:title>
		</media:content>

		<media:content url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-07-69-metablogapi/0245.PRG_5F00_pattern_5F00_thumb.png" medium="image">
			<media:title type="html">PRG_pattern</media:title>
		</media:content>
	</item>
		<item>
		<title>Best Practices for ASP.NET MVC: View (Phần 2)</title>
		<link>http://namdh.wordpress.com/2011/09/27/best-practices-for-asp-net-mvc-view/</link>
		<comments>http://namdh.wordpress.com/2011/09/27/best-practices-for-asp-net-mvc-view/#comments</comments>
		<pubDate>Tue, 27 Sep 2011 03:49:27 +0000</pubDate>
		<dc:creator>namdh</dc:creator>
				<category><![CDATA[Microsoft .NET]]></category>
		<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[Best Practices for ASP.NET MVC]]></category>

		<guid isPermaLink="false">http://namdh.wordpress.com/?p=1579</guid>
		<description><![CDATA[[Bài viết này dựa trên một tài liệu của tác giả Ben Grover (một nhà phát triển cấp cao từ Microsoft). Chúng tôi dự định sẽ đưa những thông tin này vào phần tài liệu MVC 3 trên trang MSDN. Chúng tôi hi vọng được nghe những phản hổi  và mong chờ bất kỳ góp [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=namdh.wordpress.com&amp;blog=4017103&amp;post=1579&amp;subd=namdh&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><span style="color:#ff0000;">[Bài viết này dựa trên một tài liệu của tác giả Ben Grover (một nhà phát triển cấp cao từ Microsoft). Chúng tôi dự định sẽ đưa những thông tin này vào phần tài liệu MVC 3 trên trang MSDN. Chúng tôi hi vọng được nghe những phản hổi  và mong chờ bất kỳ góp ý nào từ phía các bạn]</span></p>
<p>Bài viết này giới thiệu một tập các hướng dẫn lập trình nhắm đến các lập trình viên ASP.NET MVC. Tất nhiên, bạn, với tư cách là nhà phát triển sẽ vẫn là người quyết định cuối cùng trong việc chọn hướng dẫn nào phù hợp nhất.</p>
<ul>
<li><a href="http://namdh.wordpress.com/2011/09/27/best-practices-for-asp-net-mvc-model/">Phần 1: Model</a></li>
<li><a href="http://namdh.wordpress.com/2011/09/27/best-practices-for-asp-net-mvc-view/">Phần 2: View</a></li>
<li><a href="http://namdh.wordpress.com/2011/10/05/best-practices-for-asp-net-mvc-controller/">Phần 3: Controller</a></li>
</ul>
<p><span id="more-1579"></span></p>
<h1>Các khuyến nghị trong việc tạo View</h1>
<p>Vai trò chính của một View là trình bày nội dung của Model. View được chọn bởi Controller. Business logic không được bao gồm trong view, vì nó thuộc vai trò của lớp Model. Các kỹ thuật dùng view có thể cực kỳ mềm dẻo. Ví dụ, một view cho một trang web có thể được hiển thị bằng HTML. Một view khác của cùng Model (cùng dữ liệu), có thể được biểu diễn bằng XML và hoạt động như một Web Service.</p>
<h2>Nên: HTML phải được viết trong Views và các Partial View (chứ không phải trong controller).</h2>
<p>Một trong những ưu điểm lớn nhất của view là tính dễ đọc của các file view template. Với view engine mặc nhiên, ASP.NET cho phép bạn dùng các kiểu file view sau: các trang HTML đầy đủ (.aspx), các phần trang HTML (partial HTML view), và các master page (.master). Một trang master cho phép bạn chỉ ra định dạng tổng thể của view. Các trang master cũng có thể lồng nhau ở một số cấp để tạo ra một cây các kiểu hiển thị khác nhau.</p>
<p>Ví dụ sau cho thấy cách gọi một partial view:</p>
<pre>&lt;%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %&gt;
…
    Below is a list of items submitted by &lt;b&gt;
&lt;%= Html.Encode(ViewData["name"]) %&gt;&lt;/b&gt;.
    &lt;p&gt;

    ...
    &lt;div id="items"&gt;
        &lt;% Html.RenderPartial("ItemsByName");%&gt;
    &lt;/div&gt;
&lt;/asp:content&gt;</pre>
<p>File partial view (ItemsByName.ascx) được hiển thị ở đây:</p>
<pre>&lt;%@ Control Language="C#"  %&gt;
…
        &lt;% foreach (Seller.Controllers.Items item in (IEnumerable)ViewData.Model)
           { %&gt;
            &lt;tr&gt;
                &lt;td&gt;
                    &lt;%= Html.Encode(item.title)%&gt;
                &lt;/td&gt;
                &lt;td&gt;
                    &lt;%= Html.Encode(item.price)%&gt;
                &lt;/td&gt;
            &lt;/tr&gt;
        &lt;% } %&gt;
        &lt;/table&gt;
      &lt;% } %&gt;</pre>
<p>Partial view là một cơ chế mở rộng và dùng lại mạnh mẽ. Ví dụ, chúng ta có thể bao gồm cùng một partial view vào trong một trang quản trị, mà không cần viết lại code.</p>
<h2>Nên: truy cập dữ liệu trong view dùng ViewData</h2>
<p>ASP.NET cung cấp cách cơ chế sau cho phép truy cập dữ liệu từ các trang view:</p>
<ul>
<li>Đối tượng<strong> ViewData.Model</strong>, được tạo ra bởi phương thức action trong controller bằng cách truyền đối tượng model vào câu lệnh return (<code>return View(myModelObject)</code>).</li>
<li><strong>ViewData</strong>, cho phép bạn đưa vào bất kỳ loại dữ liệu nào vào trong dictionary trong phương thức action (ViewData[“key”] = value), và sau đó có thể được truy cập từ view.</li>
</ul>
<p>Bất cứ khi nào có thể, bạn nên ViewData.Model thay vì ViewData bởi nó chặt chẽ về kiểu dữ liệu. Thêm nữa, bạn nên dùng cơ chế truy cập dữ liệu hơn là truy cập trực tiếp đến Request/Session trực tiếp trong view.</p>
<p>Nếu bạn có một đối tượng chứa nhiểu thuộc tính cần được hiển thị, bạn nên dùng ViewData.Model và tạo strongly typed view cho đối tượng đó. Nếu bạn có một trang hiển thị chi tiết người bán (seller), lấy ví dụ, và lớp seller có các thuộc tính name, phone, address, email&#8230; khi đó bạn có thế trả về một đối tượng kiểu seller từ controller trước khi hiển thị view. Nếu bạn có các thông tin khác như số trang, tên người dùng, giờ hiện tại, hãy dùng ViewData.</p>
<p>Tránh việc truy cập dữ liệu trong view khi dùng model binding. Nói cách khác, việc truy xuất dữ liệu từ CSDL phải được thực hiện trong controller, sau đó đưa dữ liệu vào các đối tượng ViewData.Model trước khi thực thi view. Nhờ đó các đối tượng này sẽ không phải truy xuất dữ liệu trong quá trình hiển thị view.</p>
<h2>Nên: cho phép (tự động sinh) các phép kiểm tra dữ liệu phía client.</h2>
<p>Trước đây, các nhà phát triển web thường gặp khó khăn khi đảm bảo tính đồng bộ giữa các phép kiểm tra dữ liệu trên server và client. Bắt đầu từ ASP.NET MVC 2, việc này trở nên khá dễ dàng.</p>
<p>Để thêm việc kiểm tra dữ liệu phía client:</p>
<ol>
<li>Thêm phép kiểm tra vào lớp model giống như đã nói trong phần &#8220;Nên: đặt tất cả các quy tắc xác định giá trị hợp lệ của dữ liệu bên trong model.&#8221;</li>
<li>Đảm bảo các file sau có trong thư mục Scripts của project:
<ul>
<li>MicrosoftAjax.js</li>
<li>MicrosoftMvcValidation.js</li>
</ul>
</li>
<li>Thêm dòng sau vào trang chứa form cần kiểm tra:
<pre>&lt;script src="&lt;%= Url.Content("~/Scripts/MicrosoftAjax.js") %&gt;" type="text/javascript"&gt;&lt;/script&gt;

&lt;script src="&lt;%= Url.Content("~/Scripts/MicrosoftMvcValidation.js") %&gt;" type="text/javascript"&gt;&lt;/script&gt;</pre>
</li>
<li>Đặt dòng sau vào trước thẻ form:
<pre>&lt;% Html.EnableClientValidation(); %&gt;</pre>
</li>
</ol>
<p>Giờ nếu bạn thử sửa một giá trị không khớp với các phép kiểm tra, việc xác thực tính hợp lệ trên client sẽ thất bại và thông báo sẽ được chuyển ngay cho người dùng.</p>
<h2>Nên: đưa các ghi chú dạng server-side vào trong template:</h2>
<p>Nên dùng ghi chú dạng server-side trong các trang view. Các ghi chú đó sẽ được loại bỏ trước khi server trả về trang HTML.</p>
<p>Dòng sau biểu diễn một ghi chú dạng server-side:</p>
<p>&lt;%&#8211; This is a server side template comment &#8211;%&gt;</p>
<p>Đừng dùng các ghi chú dạng HTML trong các trang view vì nó sẽ được hiển thị lên trình duyệt ưeb và có thể được xem bởi một người dùng có kinh nghiệm (và có thể nguy hiểm).</p>
<h2>Nên: dùng các phương thức mở rộng của HTMLHelper.</h2>
<p>Lớp <strong>System.Web.Mvc.Html</strong> chứa nhiều phương thức mở rộng hữu ích. Các phương thức này bao gồm:</p>
<ul>
<li>Tạo form (BeginForm)</li>
<li>Tạo các trường nhập dữ liệu (checkbox, hidden, radio button, textbox)</li>
<li>Tạo link (ActionLink)</li>
<li>Chống XSS (Encode)</li>
</ul>
<p>Các phương thức mở rộng này nên được sử dụng càng nhiều càng tốt. Ví dụ, đoạn code sau tạo một link dùng route table để chuyển về action Default trên cùng controller gọi đến view hiện tại:</p>
<pre>&lt;%= Html.ActionLink(“Home page”, “Default”) %&gt;</pre>
<p>(Có thể xem thêm về các phương thức mở rộng tại đây: <a href="http://namdh.wordpress.com/2011/01/19/extension-methods/">http://namdh.wordpress.com/2011/01/19/extension-methods/</a>)</p>
<p><span style="color:#ff0000;">[Bài viết này dựa trên một tài liệu của tác giả Ben Grover (một nhà phát triển cấp cao từ Microsoft). Chúng tôi dự định sẽ đưa những thông tin này vào phần tài liệu MVC 3 trên trang MSDN. Chúng tôi hi vọng được nghe những phản hổi  và mong chờ bất kỳ góp ý nào từ phía các bạn]</span></p>
<p>Bài viết này giới thiệu một tập các hướng dẫn lập trình nhắm đến các lập trình viên ASP.NET MVC. Tất nhiên, bạn, với tư cách là nhà phát triển sẽ vẫn là người quyết định cuối cùng trong việc chọn hướng dẫn nào phù hợp nhất.</p>
<br /> Tagged: <a href='http://namdh.wordpress.com/tag/asp-net-mvc/'>ASP.NET MVC</a>, <a href='http://namdh.wordpress.com/tag/best-practices-for-asp-net-mvc/'>Best Practices for ASP.NET MVC</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/namdh.wordpress.com/1579/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/namdh.wordpress.com/1579/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/namdh.wordpress.com/1579/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/namdh.wordpress.com/1579/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/namdh.wordpress.com/1579/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/namdh.wordpress.com/1579/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/namdh.wordpress.com/1579/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/namdh.wordpress.com/1579/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/namdh.wordpress.com/1579/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/namdh.wordpress.com/1579/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/namdh.wordpress.com/1579/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/namdh.wordpress.com/1579/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/namdh.wordpress.com/1579/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/namdh.wordpress.com/1579/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=namdh.wordpress.com&amp;blog=4017103&amp;post=1579&amp;subd=namdh&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://namdh.wordpress.com/2011/09/27/best-practices-for-asp-net-mvc-view/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">namdh</media:title>
		</media:content>
	</item>
		<item>
		<title>Best Practices for ASP.NET MVC: Model (Phần 1)</title>
		<link>http://namdh.wordpress.com/2011/09/27/best-practices-for-asp-net-mvc-model/</link>
		<comments>http://namdh.wordpress.com/2011/09/27/best-practices-for-asp-net-mvc-model/#comments</comments>
		<pubDate>Tue, 27 Sep 2011 03:46:00 +0000</pubDate>
		<dc:creator>namdh</dc:creator>
				<category><![CDATA[Microsoft .NET]]></category>
		<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[Best Practices for ASP.NET MVC]]></category>

		<guid isPermaLink="false">http://namdh.wordpress.com/?p=1576</guid>
		<description><![CDATA[Bài viết sau đây được dịch từ http://blogs.msdn.com/b/aspnetue/archive/2010/09/17/second_2d00_post.aspx bởi Đào Hải Nam. ASP.NET MVC đã và đang trở nên phổ biến, với liên tiếp các phiên bản 1, 2, 3 và 4 (sẽ ra mắt cùng với .NET 4.5), ASP.NET MVC đã chứng tỏ sức mạnh của nó. Những ưu điểm của ASP.NET MVC, bao [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=namdh.wordpress.com&amp;blog=4017103&amp;post=1576&amp;subd=namdh&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Bài viết sau đây được dịch từ <a href="http://blogs.msdn.com/b/aspnetue/archive/2010/09/17/second_2d00_post.aspx">http://blogs.msdn.com/b/aspnetue/archive/2010/09/17/second_2d00_post.aspx</a> bởi Đào Hải Nam.</p>
<p>ASP.NET MVC đã và đang trở nên phổ biến, với liên tiếp các phiên bản 1, 2, 3 và 4 (sẽ ra mắt cùng với .NET 4.5), ASP.NET MVC đã chứng tỏ sức mạnh của nó. Những ưu điểm của ASP.NET MVC, bao gồm cả của mô hình MVC là: phân tách rõ ràng các phần M-V-C, cung cấp nhiều cơ chế xử lý request khác nhau, dựa trên ASP.NET &#8211; vốn đã rất mạnh mẽ, hỗ trợ nhiều view engine, có cơ chế định tuyến (routing) mềm dẻo, giúp người phát triển có thể tạo các URL thân thiện người dùng và SEO&#8230;</p>
<p>Bài viết sau cung cấp các khuyến nghị giúp nhà phát triển có thể sử dụng ASP.NET MVC một cách đúng đắn và phù hợp nhất.</p>
<p>Người dịch: <span style="color:#0000ff;">Đào Hải Nam</span></p>
<p><span style="color:#ff0000;">[Bài viết này dựa trên một tài liệu của tác giả Ben Grover (một nhà phát triển cấp cao từ Microsoft). Chúng tôi dự định sẽ đưa những thông tin này vào phần tài liệu MVC 3 trên trang MSDN. Chúng tôi hi vọng được nghe những phản hổi  và mong chờ bất kỳ góp ý nào từ phía các bạn]</span></p>
<p>Bài viết này giới thiệu một tập các hướng dẫn lập trình nhắm đến các lập trình viên ASP.NET MVC. Tất nhiên, bạn, với tư cách là nhà phát triển sẽ vẫn là người quyết định cuối cùng trong việc chọn hướng dẫn nào phù hợp nhất.</p>
<ul>
<li><a href="http://namdh.wordpress.com/2011/09/27/best-practices-for-asp-net-mvc-model/">Phần 1: Model</a></li>
<li><a href="http://namdh.wordpress.com/2011/09/27/best-practices-for-asp-net-mvc-view/">Phần 2: View</a></li>
</ul>
<p><span id="more-1576"></span></p>
<h1>Các khuyến nghị trong việc tạo Model</h1>
<p>Phần này nói về việc tạo các model. Các định nghĩa model này bao gồm business logic (cách các đối tượng hoạt động và quan hệ), validation logic (đâu là giá trị hợp lệ của một đối tượng), data logic (các đối tượng được lưu trữ như thế nào) và session logic (trạng thái của người dùng bên trong ứng dụng).</p>
<h2>Nên: Tách model ra một project riêng và tạo một assembly riêng.</h2>
<p>Với các ứng dụng có mô hình dữ liệu lớn và phức tạp, sẽ là một ý hay nếu bạn tạo một assembly riêng cho model để tránh việc lẫn lộn với các thành phần khác. Bạn sau đó có thể tham chiếu đến assembly này trong ứng dụng ASP.NET MVC.</p>
<h2>Nên: đặt tất cả business logic trong model.</h2>
<p>Nếu đặt tất cả business logic bên trong model, bạn sẽ bảo vệ view và controller khỏi việc phải tạo các quyết định liên quan đến quy tắc xử lý dữ liệu (business logic). Bạn cũng sẽ có được thêm những lợi ích sau:</p>
<ul>
<li>Giảm việc trùng lắp các business logic.</li>
<li>View dễ đọc hơn vì không chứa các quy tắc xử lý.</li>
<li>Việc kiểm lỗi các quy tắc xử lý cũng sẽ độc lập với model.</li>
</ul>
<p>Ví dụ, nếu bạn có một yêu cầu hiển thị tên người dùng với họ đứng trước, bạn có thể đặt nó trong view như sau:</p>
<pre>&lt;% if (String.Compare((string)TempData["displayLastNameFirst"], "on") == 0)
       { %&gt;
        Welcome, &lt;%= Model.lastName%&gt;, &lt;%= Model.firstName%&gt;
    &lt;% }
       else
       { %&gt;
        Welcome, &lt;%= Model.firstName%&gt; &lt;%= Model.lastName%&gt;
    &lt;% } %&gt;</pre>
<p>Tuy nhiên, bạn sẽ phải lặp lại việc trên trong tất cả các nơi cần hiển thị theo cùng cách. Thay vì vậy, bạn có thể đặt một quy tắc &#8220;hiển thị họ trước&#8221; trong model bằng cách thêm một thuộc tính giống như sau:</p>
<pre>public string combinedName
{
    get
    {
        return (displayLastNameFirst ? lastName + " " + firstName : firstName + " " + lastName);
    }
    private set
    {
        ;
    }
}</pre>
<p>Như vậy, view của bạn sẽ đơn giản như sau:</p>
<pre>&lt;% Welcome, &lt;%= Model.combinedName %&gt; %&gt;</pre>
<h2>Nên: đặt tất cả các quy tắc xác định giá trị hợp lệ của dữ liệu bên trong model.</h2>
<p>Tất cả các dữ liệu được nhập vào đều phải được kiểm tra tại model. Việc kiểm tra này tuy có thể thực hiện từ phía client, với mục đích tăng hiệu suất. Nhưng nếu thực hiện tại client, việc nó có thể bị bỏ qua hoặc xử lý theo cách không mong muốn (với một công cụ nào đó, kiểu như Fiddler).</p>
<p>Bạn có thể dùng ModelState để thêm các quy tắc kiểm tra. Ví dụ sau cho thấy cách thêm các phép kiểm tra dữ liệu vào ModelState một cách tường minh:</p>
<pre>if (String.IsNullOrEmpty(userName))
{
   ModelState.AddModelError("username", Resources.SignUp.UserNameError);
}</pre>
<p>Tuy nhiên, với .NET Framework, <strong>System.ComponentModel.DataAnnotations</strong> được khuyên dùng để làm điều này. Nó cho phép thêm các attribute vào cho các thuộc tính của lớp model, giống ví dụ sau:</p>
<pre>public class User
{
   [Required(ErrorMessageResourceName = "nameRequired", ErrorMessageResourceType = typeof(Resources.User))]
   public String userName { get; set; }
       ...
}</pre>
<h2>Nên: định nghĩa interface cho lớp truy cập dữ liệu</h2>
<p>Bạn nên tạo một interface với các phương thức cung cấp chức năng truy cập dữ liệu. Điều này cho phép giảm phụ thuộc giữa các thành phần trong thiết kế chương trình.</p>
<p>Bạn có thể cân nhắc việc dùng Entity Framework hay LINQ to SQL để tạo tầng truy cập dữ liệu. Cả hai Entity Framework và LINQ to SQL để cho phép sử dụng các Stored Procedure.</p>
<h2>Nên: đặt tất cả session logic trong model.</h2>
<p>Sẽ là vượt quá khỏi phạm vi của bài viết này nếu muốn nói sâu về một số kỹ thuật lưu trữ trạng thái session trong model. Ban đầu, ta chỉ xem sơ qua một số cách có thể dùng để lưu trạng thái session:</p>
<table width="400" border="1" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<th valign="top" width="130">Kỹ thuật</th>
<th valign="top" width="220">Ưu điểm</th>
<th valign="top" width="220">Nhược điểm</th>
</tr>
<tr>
<td valign="top" width="130">Lưu ngay trong tiến trình</td>
<td valign="top" width="220">Không phải cài đặt gì thêm.</td>
<td valign="top" width="220">Không dùng được nếu ứng dụng web cần được mở rộng ra (nhiều server).</td>
</tr>
<tr>
<td valign="top" width="130">Dùng dịch vụ lưu trữ session</td>
<td valign="top" width="220">Dịch vụ chạy độc lập trên mỗi máy tính trong web farm.<br />
Nhanh hơn cách dùng CSDL.</td>
<td valign="top" width="220">Dữ liệu trong session bị mất nếu dịch vụ bị tắt.</td>
</tr>
<tr>
<td valign="top" width="130">Dùng CSDL</td>
<td valign="top" width="220">Dữ liệu trong session được toàn vẹn.</td>
<td valign="top" width="220">Chậm hơn các cánh trên. Chi phí quản lý tương đối cao.</td>
</tr>
</tbody>
</table>
<br /> Tagged: <a href='http://namdh.wordpress.com/tag/asp-net-mvc/'>ASP.NET MVC</a>, <a href='http://namdh.wordpress.com/tag/best-practices-for-asp-net-mvc/'>Best Practices for ASP.NET MVC</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/namdh.wordpress.com/1576/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/namdh.wordpress.com/1576/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/namdh.wordpress.com/1576/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/namdh.wordpress.com/1576/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/namdh.wordpress.com/1576/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/namdh.wordpress.com/1576/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/namdh.wordpress.com/1576/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/namdh.wordpress.com/1576/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/namdh.wordpress.com/1576/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/namdh.wordpress.com/1576/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/namdh.wordpress.com/1576/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/namdh.wordpress.com/1576/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/namdh.wordpress.com/1576/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/namdh.wordpress.com/1576/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=namdh.wordpress.com&amp;blog=4017103&amp;post=1576&amp;subd=namdh&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://namdh.wordpress.com/2011/09/27/best-practices-for-asp-net-mvc-model/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">namdh</media:title>
		</media:content>
	</item>
		<item>
		<title>Các câu hỏi thường gặp về khóa học NB1</title>
		<link>http://namdh.wordpress.com/2011/09/06/nb1-qa/</link>
		<comments>http://namdh.wordpress.com/2011/09/06/nb1-qa/#comments</comments>
		<pubDate>Tue, 06 Sep 2011 04:34:23 +0000</pubDate>
		<dc:creator>namdh</dc:creator>
				<category><![CDATA[Training]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[NB1]]></category>

		<guid isPermaLink="false">http://namdh.wordpress.com/?p=1555</guid>
		<description><![CDATA[Q. Tôi chưa biết gì về lập trình, liệu tôi có thể tham gia không? A. Không. đây là khóa học nâng cao, được thiết kế để tăng cường thêm kinh nghiệm và kỹ năng làm việc, cũng như bổ sung kiến thức nền tảng để học viên có thể tự học, tự nghiên cứu [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=namdh.wordpress.com&amp;blog=4017103&amp;post=1555&amp;subd=namdh&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><span style="color:#008000;">Q. Tôi chưa biết gì về lập trình, liệu tôi có thể tham gia không?</span></p>
<p>A. Không. đây là khóa học nâng cao, được thiết kế để tăng cường thêm kinh nghiệm và kỹ năng làm việc, cũng như bổ sung kiến thức nền tảng để học viên có thể tự học, tự nghiên cứu sau này.</p>
<p>Bạn có thể học để có kỹ năng lập trình cơ bản, sau đó tham gia cũng không muộn.</p>
<p><span style="color:#008000;">Q. Tôi không đọc được tài liệu chuyên ngành, tôi có thể học được không?</span></p>
<p>A. Không. bạn sẽ phải tìm kiếm tài liệu, tự học, tự nghiên cứu rất nhiều, vậy nên không có tiếng Anh, bạn sẽ khó theo nổi.</p>
<p>Trình độ tiếng Anh yêu cầu là có thể học hiểu (ít nhất cũng là 50-60%). Hãy đọc bài sau để hiểu tầm quan trọng của tiếng Anh trong ngành IT (<a href="http://namdh.wordpress.com/2010/10/29/some-tips-for-it-students/">http://namdh.wordpress.com/2010/10/29/some-tips-for-it-students/</a>)</p>
<p><span style="color:#008000;">Q. Tôi chỉ muốn học phần lập trình ASP.NET (hoặc Winform), liệu có được không?</span></p>
<p>A. Không. Câu trả lời không này là vì chính bạn, khi tự bó hẹp mình trong một phạm vi nào đó, bạn đã đóng một cánh cửa trước mặt, lập trình Web hay Application không phải là các tùy chọn loại trừ nhau. Việc học mang lại lợi ích ở cấp số nhân: bạn học thêm một, bạn sẽ biết được thêm 10.</p>
<p><span style="color:#008000;">Q. Tôi đã học OOP ở trường, tôi không muốn học phần này có được không?</span></p>
<p>A. Tùy trường hợp, nhưng trên thực tế, đáng tiếc đa số chỉ hiểu OOP theo cách một coder thuần túy, mà không phải cách của một designer, thậm chí nhiều người vẫn hiểu sai các khái niệm có trong OOP. Làm sao bạn lập trình, phân tích thiết kế hướng đối tượng tốt nếu bạn không thực sự hiểu hoặc hiểu sai nó?</p>
<p><span style="color:#008000;">Q. Tôi sắp ra trường rồi, liệu có còn kịp để học không?</span></p>
<p>A. Học chẳng bao giờ là muộn, bạn nghĩ những người khác đang đi làm thì không phải học sao?</p>
<p><span style="color:#008000;">Q. Tôi thấy chương trình quá nhiều, liệu có thể học kịp không?</span></p>
<p>A. Thật dễ dàng cho tôi và cả cho bạn nếu tôi kéo dài chương trình này trong 1 năm hoặc 2 năm. Nhưng dễ dàng như vậy để làm gì? Bạn muốn thành công, vậy phải đổ mồ hôi thôi. Thời lượng dành cho khóa học trên lớp chỉ chiếm không tới 50%, còn lại bạn sẽ phải tự học, tất nhiên tôi sẽ phải cho bạn biết tự học gì và như thế nào.</p>
<p><span style="color:#008000;">Q. Tôi thấy có nhiều nơi cũng dạy những thứ giống trong NB1, vậy ưu điểm của chương trình này là gì?</span></p>
<p>A. NB1 là chương trình kết hợp 1 phần trong chương trình đại học và một phần trong các chương trình đào tạo LTV như của NIIT hay Aptech, đó là 50% ưu điểm, 50% còn lại là bạn sẽ được truyền đạt những kinh nghiệm mà những người khác phải mất nhiều năm mới có được.</p>
<p><span style="color:#008000;">Q. Lớp học có bao nhiêu người?</span></p>
<p>A. Một lớp chỉ có tối đa 10 người. Nếu lớp đã đầy, bạn có thể phải chờ khóa tiếp theo.</p>
<p><span style="color:#008000;">Q. Bài giảng có slide không?</span></p>
<p>A. Có. Bài giảng có dùng slide + demo, tuy nhiên, về nguyên tắc, slide chỉ chứa thông tin cô đọng, hoặc tổng kết.</p>
<p><span style="color:#008000;">Q. Có giáo trình không?</span></p>
<p>A. Không có giáo trình riêng. Khi học đến phần nào, giảng viên sẽ giới thiệu chương trình học và tài liệu (từ các sách, website&#8230;)</p>
<p><span style="color:#008000;">Q. Nếu bận công việc phải nghỉ nhiều thì thế nào?</span></p>
<p>A. Nếu thực sự không đi học được, bạn có thể xin nghỉ và đăng ký để giảng viên giảng lại trong một giờ khác. Tuy nhiên, phải cố gắng nghỉ càng ít càng tốt. Nếu phải nghỉ nhiều có thể chờ và học cùng lớp tiếp theo (riêng phần đã nghỉ, các bài khác học bình thường).</p>
<br /> Tagged: <a href='http://namdh.wordpress.com/tag/net/'>.net</a>, <a href='http://namdh.wordpress.com/tag/nb1/'>NB1</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/namdh.wordpress.com/1555/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/namdh.wordpress.com/1555/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/namdh.wordpress.com/1555/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/namdh.wordpress.com/1555/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/namdh.wordpress.com/1555/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/namdh.wordpress.com/1555/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/namdh.wordpress.com/1555/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/namdh.wordpress.com/1555/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/namdh.wordpress.com/1555/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/namdh.wordpress.com/1555/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/namdh.wordpress.com/1555/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/namdh.wordpress.com/1555/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/namdh.wordpress.com/1555/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/namdh.wordpress.com/1555/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=namdh.wordpress.com&amp;blog=4017103&amp;post=1555&amp;subd=namdh&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://namdh.wordpress.com/2011/09/06/nb1-qa/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">namdh</media:title>
		</media:content>
	</item>
		<item>
		<title>Khóa học NB1 &#8211; Nếu bạn muốn trở thành lập trình viên chuyên nghiệp</title>
		<link>http://namdh.wordpress.com/2011/08/26/course-nb1/</link>
		<comments>http://namdh.wordpress.com/2011/08/26/course-nb1/#comments</comments>
		<pubDate>Fri, 26 Aug 2011 11:18:34 +0000</pubDate>
		<dc:creator>namdh</dc:creator>
				<category><![CDATA[Training]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[asp.net]]></category>

		<guid isPermaLink="false">http://namdh.wordpress.com/?p=1540</guid>
		<description><![CDATA[Khóa học sau được thiết kế dành cho bạn nếu: - Bạn đã biết lập trình nhưng cảm thấy khả năng vẫn chưa đáp ứng được cho công việc sau này, hoặc - Bạn có kỹ năng code, nhưng thiếu kiến thức nền tảng để có thể tự học, tự nghiên cứu, hoặc - Bạn [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=namdh.wordpress.com&amp;blog=4017103&amp;post=1540&amp;subd=namdh&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h3><span style="text-decoration:underline;"><strong>Khóa học sau được thiết kế dành cho bạn nếu:</strong></span></h3>
<p>- Bạn đã biết lập trình nhưng cảm thấy khả năng vẫn chưa đáp ứng được cho công việc sau này, hoặc</p>
<p>- Bạn có kỹ năng code, nhưng thiếu kiến thức nền tảng để có thể tự học, tự nghiên cứu, hoặc</p>
<p>- Bạn đã đi làm, nhưng bối rối, không tìm được định hướng cho bản thân để phát triển nghề nghiệp, hoặc</p>
<p>- Bạn đang đi học, nhưng vẫn muốn có thêm kinh nghiệm làm việc.</p>
<p>(Xem hướng dẫn đăng ký ở dưới)</p>
<h3><span style="text-decoration:underline;"><strong>Khóa học này sẽ mang lại cho bạn:</strong></span></h3>
<p>- Kiến thức nền tảng vững chắc: đây là mục tiêu quan trọng nhất của khóa học, OOP, TCP/IP, OS&#8230; là những thứ nền tảng nhất, và cũng là quan trọng nhất, bạn cần phải <span style="text-decoration:underline;">biết</span>, <span style="text-decoration:underline;">hiểu</span> cách nó làm việc một cách <span style="text-decoration:underline;">đúng đắn</span> (hầu hết những người tôi đã phỏng vấn cho vị trí senior developer không trả lời được hết những câu hỏi về những thứ được coi là cơ bản này).</p>
<p>- Kỹ năng lập trình thành thạo: Một núi các bài tập và project bạn phải hoàn thành sẽ mang lại cho bạn nhiều kỹ năng và kinh nghiệm.</p>
<p>- Khả năng tự học: Thêm một núi các bài nghiên cứu và tự học sẽ hoàn thiện khả năng tự học của bạn.</p>
<p>- Kinh nghiệm làm việc như tại các công ty phần mềm: Tiêu chuẩn và quy trình hoàn thành của các dự án sẽ giúp các bạn hiểu được sự khác nhau giữa một đồ án &#8211; bài tập lớn trong trường học với các dự án &#8220;kiếm được tiền&#8221;.</p>
<p>- Biết được &#8220;đời&#8221; thế nào <img src='http://s0.wp.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> : Giảng viên nhiều kinh nghiệm sẽ truyền đạt lại cho bạn các kỹ năng đi phỏng vấn, viết CV, thuyết trình, viết tài liệu. Giảng viên cũng có nhiệm vụ giúp bạn tìm hiểu và đánh giá những khả năng của bạn, qua đó giúp bạn có được định hướng trong tương lai.</p>
<h3><span style="text-decoration:underline;"><strong>Khóa học sau yêu cầu bạn:</strong></span></h3>
<p>- Yêu công việc lập trình và mong muốn trở thành một lập trình viên giỏi (và lương cao, he he): Xin nhấn mạnh là bạn yêu nó &#8211; hoặc chí ít cũng là rất thích.</p>
<p>- Tiếng Anh đủ để đọc tài liệu (có thể dùng từ điển).</p>
<p>- Tuân thủ kỷ luật, nội quy theo chương trình học.</p>
<p>- Đảm bảo thời gian học, không vắng mặt, đảm bảo dành ít nhất 14h/tuần cho việc học (bao gồm giờ trên lớp), <span style="text-decoration:underline;">bạn sẽ không thể hoàn thành bài tập/dự án nếu không dành đủ chừng đó thời gian</span>. (14h/tuần chỉ bằng 1/3 thời gian sau này các bạn đi làm trên lý thuyết, và trên thực tế có thể chỉ bằng 1/4 hay 1/5).</p>
<p>-Hoàn thành đầy đủ các bài tập/dự án/báo cáo&#8230; Các bài này sẽ được đánh giá, chấm điểm, nhờ đó giảng viên có thể biết bạn mạnh yếu chỗ nào để điều chỉnh. Ngoài ra, <span style="text-decoration:underline;">điểm số cũng sẽ quyết định một phần vào việc bạn có được tiếp tục theo học hay không</span>.</p>
<h3><span style="text-decoration:underline;"><strong>Nội dung chương trình:</strong></span></h3>
<p><span style="color:#008000;">- C# cơ bản:</span></p>
<p>+ Các khái niệm cơ bản của OOP: inheritance, abstraction, polymorphism, encapsulation.</p>
<p>+ Cấu trúc dữ liệu và thuật toán: list, tree, search, sort.</p>
<p><span style="color:#008000;">- Kiến trúc máy tính và Hệ điều hành:</span></p>
<p>+ Bit/byte&#8230;</p>
<p>+ Quản lý bộ nhớ.</p>
<p>+ Quản lý đĩa.</p>
<p>+ CPU.</p>
<p><span style="color:#008000;">- Lập trình mạng TCP/IP:</span></p>
<p>+ Cách đánh địa chỉ, cấu trúc packet, cơ chế định tuyến&#8230;</p>
<p>+ Giao thức HTTP (GET, POST, Session, Cookie&#8230;).</p>
<p>+ Viết ứng dụng với socket.</p>
<p>+ Các khái niệm cơ bản trong bảo mật: mã hóa đối xứng, bất đối xứng, băm, SSL, chữ ký điện tử&#8230;</p>
<p><span style="color:#008000;">- Windows Form:</span></p>
<p>+ Giới thiệu.</p>
<p>+ Control: các control chuẩn, menu, toolstrip&#8230;</p>
<p>+ User control.</p>
<p><span style="color:#008000;">- Ngôn ngữ SQL với SQL Server:</span></p>
<p>+ Cơ bản về CSDL quan hệ.</p>
<p>+ Cơ bản về SQL Server.</p>
<p>+ TABLE/VIEW</p>
<p>+ INSERT/SELECT/UPDATE/DELETE</p>
<p>+ Transaction</p>
<p>+ PROCEDURE/FUNCTION</p>
<p><span style="color:#008000;">- Truy cập CSDL với ADO.NET:</span></p>
<p>+ Tổng quan về ADO.NET</p>
<p>+ DataSet, DataTable, DataAdapter&#8230;</p>
<p>+ Truy vấn, cập nhật dữ liệu.</p>
<p><span style="color:#008000;">- Lập trình Web với Web Forms.</span></p>
<p>+ Giới thiệu</p>
<p>+ Sử dụng các control chuẩn, các control liên quan đến dữ liệu.</p>
<p>+ Cấu hình ứng dụng web.</p>
<p><span style="color:#008000;">- Truy cập CSDL với Entity Framework.</span></p>
<p>+ Giới thiệu.</p>
<p>+ LINQ.</p>
<p>+ Tạo mô hình, các thao tác truy vấn, cập nhật trên dữ liệu.</p>
<p><span style="color:#008000;">- Lập trình Web với ASP.NET MVC.</span></p>
<p>+ Mô hình MVC.</p>
<p>+ Tạo ứng dụng với ASP.NET MVC.</p>
<p><span style="color:#008000;">- Xây dựng ứng dụng phân tán.</span></p>
<p>+ Giới thiệu ứng dụng phân tán.</p>
<p>+ .NET Remoting.</p>
<p>+ Mô hình 3-tiers.</p>
<p><span style="color:#008000;">- Kỹ năng thuyết trình.</span></p>
<p><span style="color:#008000;">- Kỹ năng phỏng vấn.</span></p>
<p>Khoảng 15%-20% thời lượng khóa học dành cho việc truyền đạt kinh nghiệm, cũng như đào tạo kỹ năng mềm.</p>
<p><span style="color:#ff6600;">Chương trình học kéo dài khoảng 6 tháng (dự kiến), 3 buổi/tuần, 1 buổi 2 tiếng. Học phí: 1M/tháng. Ưu tiên học viên có laptop. </span></p>
<p>Học tại Quận 3, phía sau CoopMart Nhiêu Lộc. ĐT: <span style="color:#ff6600;">0904098052</span><span style="color:#ff6600;"><br />
</span></p>
<p><span style="text-decoration:underline;"><strong>Về giảng viên:</strong></span></p>
<p>Tên: Đào Hải Nam</p>
<p>Tuổi: không già lắm</p>
<p>Kinh nghiệm:</p>
<p>- Hơn 12 năm làm trong ngành phần mềm, là key person trong một số dự án tài chính, viễn thông và logistics.</p>
<p>- 2,5 năm làm giảng viên NIIT (senior).</p>
<p>- Đã từng phỏng vấn tuyển dụng cho nhiều vị trí khác nhau như Senior Developer, giảng viên NIIT&#8230;</p>
<p>- Có 3 bài báo trên PCWORLD VN (từ thời tờ tạp chí này còn khá mang tính học thuật chứ không như bây giờ): Thay đổi bảng màu trong chế độ đồ họa (Pascal &#8211; 1996), Cài mật mã vào chương trình (1997 &#8211; ASSEMBLY), Tự tạo công cụ phòng chống file virus (1998 &#8211; ASSEMBLY).</p>
<p>- Tác giả phần mềm Dalat Anti Virus của thiên niên kỷ trước (không nổi tiếng lắm <img src='http://s0.wp.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> ), và nhiều phần mềm không nổi tiếng khác <img src='http://s0.wp.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> .</p>
<p>- Làm việc với Java từ 1998 và với .NET từ 2003.</p>
<h3><span style="text-decoration:underline;">Hướng dẫn đăng ký:</span></h3>
<p>Trước khi đăng ký, hãy đảm bảo bạn thỏa mãn các điều kiện trong phần &#8220;<strong>Khóa học sau yêu cầu bạn&#8221;</strong> (xem ở trên). Nếu không theo kịp chương trình, không hoàn thành các bài học, nghỉ quá nhiều&#8230; bạn có thể sẽ không được tiếp tục theo học.</p>
<p><span style="text-decoration:underline;"><span style="color:#ff6600;text-decoration:underline;">Để đăng ký, bạn gọi điện đến số 0904098052, sau đó viết một email, trong đó trình bày tên, tuổi, ĐT, tình trạng kiến thức (đã học/làm gì&#8230;), lý do muốn tham gia khóa học, gửi về địa chỉ daohainam@gmail.com. </span></span></p>
<p>&nbsp;</p>
<p>(Xem các câu hỏi và trả lời về khóa học này tại đây: <a href="http://namdh.wordpress.com/2011/09/06/nb1-qa/">http://namdh.wordpress.com/2011/09/06/nb1-qa/</a>)</p>
<br /> Tagged: <a href='http://namdh.wordpress.com/tag/net/'>.net</a>, <a href='http://namdh.wordpress.com/tag/aspnet/'>asp.net</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/namdh.wordpress.com/1540/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/namdh.wordpress.com/1540/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/namdh.wordpress.com/1540/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/namdh.wordpress.com/1540/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/namdh.wordpress.com/1540/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/namdh.wordpress.com/1540/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/namdh.wordpress.com/1540/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/namdh.wordpress.com/1540/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/namdh.wordpress.com/1540/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/namdh.wordpress.com/1540/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/namdh.wordpress.com/1540/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/namdh.wordpress.com/1540/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/namdh.wordpress.com/1540/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/namdh.wordpress.com/1540/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=namdh.wordpress.com&amp;blog=4017103&amp;post=1540&amp;subd=namdh&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://namdh.wordpress.com/2011/08/26/course-nb1/feed/</wfw:commentRss>
		<slash:comments>46</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">namdh</media:title>
		</media:content>
	</item>
		<item>
		<title>Thực hiện các tính năng CRUD với Entity Framework trong ứng dụng ASP.NET MVC</title>
		<link>http://namdh.wordpress.com/2011/07/22/implementing-basic-crud-functionality-with-the-entity-framework-in-asp-net-mvc-application/</link>
		<comments>http://namdh.wordpress.com/2011/07/22/implementing-basic-crud-functionality-with-the-entity-framework-in-asp-net-mvc-application/#comments</comments>
		<pubDate>Fri, 22 Jul 2011 03:35:47 +0000</pubDate>
		<dc:creator>namdh</dc:creator>
				<category><![CDATA[Microsoft .NET]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[Getting Started with EF using MVC]]></category>
		<category><![CDATA[mvc]]></category>

		<guid isPermaLink="false">http://namdh.wordpress.com/?p=1514</guid>
		<description><![CDATA[Trong bài viết trước, bạn đã tạo một ứng dụng MVC cho phép lưu trữ và hiển thị dữ liệu dùng Entity Framework và SQL Server Compact. Trong phần này bạn sẽ xem lại và tùy biến các câu lệnh cho phép xem, thêm, xóa, sửa dữ liệu mà trình hỗ trợ của MVC đã [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=namdh.wordpress.com&amp;blog=4017103&amp;post=1514&amp;subd=namdh&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Trong bài viết trước, bạn đã tạo một ứng dụng MVC cho phép lưu trữ và hiển thị dữ liệu dùng Entity Framework và SQL Server Compact. Trong phần này bạn sẽ xem lại và tùy biến các câu lệnh cho phép xem, thêm, xóa, sửa dữ liệu mà trình hỗ trợ của MVC đã tự động tạo cho bạn trong các view và controller.</p>
<div>
<p>Ghi chú: Trong thực tế, người ta thường dùng mẫu thiết kế Repository để tạo lớp trừu tượng giữa controller và DAL. Để giữ cho bài viết được đơn giản, bạn sẽ không xây dựng một repository cho tới các bài viết sau trong cùng loạt bài này.</p>
<p>(CRUD: Create, Read, Update, Delete)</p>
<p><span id="more-1514"></span></p>
<p>Trong bài này, bạn sẽ tạo các trang web sau:</p>
</div>
<p><img src="http://www.asp.net/media/897140/Windows-Live-Writer_0b3cfafc47ec_B5A4_Student_Details_page.png" alt="Student_Details_page" width="637" height="897" border="0" /></p>
<p><img src="http://www.asp.net/media/897145/Windows-Live-Writer_0b3cfafc47ec_B5A4_Student_Edit_page.png" alt="Student_Edit_page" width="636" height="762" border="0" /></p>
<p><img src="http://www.asp.net/media/897150/Windows-Live-Writer_0b3cfafc47ec_B5A4_Student_Create_page.png" alt="Student_Create_page" width="637" height="769" border="0" /></p>
<p><img src="http://www.asp.net/media/897155/Windows-Live-Writer_0b3cfafc47ec_B5A4_Student_delete_page.png" alt="Student_delete_page" width="647" height="759" border="0" /></p>
<h2>Tạo một trang hiển thị thông tin chi tiết</h2>
<p>Vì Enrollments là một tập hợp nên mã tự động sinh ra cho trang Index bỏ qua thuộc tính này, tuy nhiên trong trang Details bạn sẽ hiển thị nội dung của nó dưới dạng một bảng HTML.</p>
<p>Trong Controllers\StudentController.cs, action method của trang Details sẽ giống như ví dụ sau:</p>
<pre>public ViewResult Details(int id)
{
    Student student = db.Students.Find(id);
    return View(student);
}</pre>
<p>Đoạn lệnh trên dùng phương thức Find để lấy về một thực thể Student tương ứng với khóa bạn truyền vào thông qua thuộc tính id. Giá trị của id đến từ tham số trên liên kết đến trang Details trên trang Index.</p>
<p>Mở Views\Student\Details.cshtml. Các trường được hiển thị nhờ phương thức DisplayFor, giống như ví dụ dưới đây:</p>
<pre>&lt;div class="display-label"&gt;LastName&lt;/div&gt;
&lt;div class="display-field"&gt;
    @Html.DisplayFor(model =&gt; model.LastName)
&lt;/div&gt;</pre>
<p>Để hiển thị danh sách các Enrollment, thêm đoạn lệnh sau vào phía sau trường EnrollmentDate, ngay phía trước thẻ đóng fieldset:</p>
<pre>&lt;div class="display-label"&gt;
    @Html.LabelFor(model =&gt; model.Enrollments)
&lt;/div&gt;
&lt;div class="display-field"&gt;
    &lt;table&gt;
        &lt;tr&gt;
            &lt;th&gt;Course Title&lt;/th&gt;
            &lt;th&gt;Grade&lt;/th&gt;
        &lt;/tr&gt;
        @foreach (var item in Model.Enrollments)
        {
            &lt;tr&gt;
                &lt;td&gt;
                    @Html.DisplayFor(modelItem =&gt; item.Course.Title)
                &lt;/td&gt;
                &lt;td&gt;
                    @Html.DisplayFor(modelItem =&gt; item.Grade)
                &lt;/td&gt;
            &lt;/tr&gt;
        }
    &lt;/table&gt;
&lt;/div&gt;</pre>
<p>Đoạn lệnh này duyệt qua toàn bộ các thực thể có trong thuộc tính Enrollments. Với mỗi thực thể Enrollment, nó sẽ hiển thị tên khóa học và xếp loại. Tên khóa khọc được lấy về từ thực thể Course của Enrollments. Tất cả dữ liệu này sẽ được lấy về từ CSDL một cách tự động khi cần (nói cách khác, bạn đang dùng lazy loading, vì bạn không chỉ ra nó là eager loading nên khi lần đầu tiên truy cập vào thuộc tính này, một câu query sẽ được gửi đến CSDL để lấy dữ liệu. Bạn có thể đọc thêm về lazy loading và eager loading trong bài &#8220;Đọc các dữ liệu quan hệ&#8221; trong cùng loạt bài này).</p>
<p>Chạy trang trên bằng cách nhấn vào tab Students và nhấn lên Details. Bạn sẽ thấy một danh sách các khóa học:</p>
<p><img src="http://www.asp.net/media/897160/Windows-Live-Writer_0b3cfafc47ec_B5A4_Student_Details_page_1.png" alt="Student_Details_page" width="637" height="897" border="0" /></p>
<h2>Creating a Create Page Tạo một trang tạo mới</h2>
<p>Trong <em>Controllers\StudentController.cs</em>, thay thế phương thức action <code>HttpPost</code> <code>Create</code> với đoạn lệnh sau để thêm một khối <code>try-catch</code> vào trong phương thức:</p>
<pre>[HttpPost]
public ActionResult Create(Student student)
{
    try
    {
        if (ModelState.IsValid)
        {
            db.Students.Add(student);
            db.SaveChanges();
            return RedirectToAction("Index");
        }
    }
    catch (DataException)
    {
        //Log the error (add a variable name after DataException)
        ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
    }
    return View(student);
}</pre>
<p>Đoạn lệnh trên thêm một thực thể Student được tạo bởi ASP.NET MVC model binder vào tập Students và lưu vào CSDL. (<em>Model binder</em> chỉ đến một tính năng có trong ASP.NET MVC cho phép dễ dàng làm việc với dữ liệu được gửi lên từ một form; trong đó một model binder sẽ chuyển các giá trị gửi lên từ form thành kiểu có trong .NET Framework và đưa chúng vào các action method dưới dạng các tham số. Trong trường hợp này, model binder khởi tạo một thực thể Student cho bạn và dùng các giá trị từ tập FormCollection.</p>
<p>Đoạn try-catch là thứ duy nhất khác nhau giữa đoạn lệnh bạn thay thế và đoạn được tự động sinh ra bởi trình hỗ trợ. Nếu một exception thừa kế từ DataException xảy ra khi đang lưu lại thay đổi, một thông báo lỗi sẽ xuất hiện. Các dạng lỗi này xảy ra thường do một  yếu tố từ bên ngoài hơn là lỗi lập trình, vậy nên người dùng được khuyên nên thử lại lần nữa. Đoạn lệnh trong <em>Views\Student\Create.cshtml </em>tương tự như cái bạn thấy trong Details.cshtml, ngoại từ EditorFor và ValidationMessageFor được dùng cho mỗi trường thay vì DisplayFor. Ví dụ sau cho thấy những thay đổi đó:<em><br />
</em></p>
<pre>&lt;div class="editor-label"&gt;
    @Html.LabelFor(model =&gt; model.LastName)
&lt;/div&gt;
&lt;div class="editor-field"&gt;
    @Html.EditorFor(model =&gt; model.LastName)
    @Html.ValidationMessageFor(model =&gt; model.LastName)
&lt;/div&gt;</pre>
<p>Không có thay đổi trong file <em>Create.cshtml</em>.</p>
<p>Nhấn lên tab <strong>Students</strong> và nhấn tiếp <strong>Create New</strong>.</p>
<p><img src="http://www.asp.net/media/897165/Windows-Live-Writer_0b3cfafc47ec_B5A4_Student_Create_page_1.png" alt="Student_Create_page" width="637" height="769" border="0" /></p>
<p>Phần kiểm tra tính hợp lệ của dữ liệu mặc nhiên được thực hiện. Nhập tên và một ngày không hợp lệ, sau đó nhấn <strong>Create</strong>, bạn sẽ thấy hiện ra thông báo lỗi.</p>
<p><img src="http://www.asp.net/media/897170/Windows-Live-Writer_0b3cfafc47ec_B5A4_Students_Create_page_error_message.png" alt="Students_Create_page_error_message" width="651" height="769" border="0" /></p>
<p>Trong trường hợp này bạn sẽ thấy thông báo được tạo bởi trình kiểm tra javascript chạy trên máy người dùng. Nhưng dữ liệu cũng được kiểm tra trên server. Do vậy ngay cả nếu phần kiểm tra bằng javascript không được thực hiện, dữ liệu lỗi cũng vẫn bị chặn lại và một exception sẽ xảy ra trên phía server.</p>
<p>Đổi ngày sang một giá trị hợp lệ như 9/1/2005 và nhấn <strong>Create</strong> để xem sinh viên mới xuất hiện trên trang <strong>Index</strong>.</p>
<p><img src="http://www.asp.net/media/897175/Windows-Live-Writer_0b3cfafc47ec_B5A4_Students_Index_page_with_new_student.png" alt="Students_Index_page_with_new_student" width="649" height="749" border="0" /></p>
<h2>Tạo một trang cập nhật</h2>
<p>Trong <em>Controllers\StudentController.cs</em>, phương thức <code>HttpGet</code> <code>Edit</code> (cái không có thuộc tính <code>HttpPost</code>) dùng phương thức <code>Find</code> để lấy về thực thể <code>Student</code> được chọn, như bạn đã thấy trong phương thức <code>Details</code>. Bạn không cần thay đổi phương thức này.</p>
<p>Tuy nhiên, thay thế phương thức action <code>HttpPost</code> <code>Edit</code> với đoạn lệnh sau để thêm vào khối <code>try-catch</code>:</p>
<pre>[HttpPost]
public ActionResult Edit(Student student)
{
    try
    {
        if (ModelState.IsValid)
        {
            db.Entry(student).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
    }
    catch (DataException)
    {
        //Log the error (add a variable name after DataException)
        ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
    }
    return View(student);
}</pre>
<p>Đoạn lệnh trên tương tự với cái bạn thấy trong phương thức HttpPost Create. Tuy nhiên, thay vì thêm một thực thể được tạo mởi model binder vào tập thực thể, đoạn lệnh trên đặt một cờ của thực thể để chỉ ra nó đã bị thay đổi. Khi phương thức SaveChanges được gọi, cờ Modified làm cho Entity Framework tạo ra các phát biểu để cập nhật dòng tương ứng trong CSDL. Tất cả các cột sẽ được cập nhật, bao gồm cả các cột người dùng không thay đổi, và bỏ qua các phép kiểm tra xem dữ liệu có  bị thay đổi bởi người dùng khác hay không. (Bạn sẽ được học về xử lý thay đổi dữ liệu đồng thời trong bài Handling Concurrency trong cùng loạt bài này).</p>
<h3>Trạng thái của thực thể và các phương thức Attach, Save Changes</h3>
<p>Đối tượng database context quản lý các thực thể trong bộ nhớ để biết nó có được đồng bộ với dòng tương ứng trong CSDL hay không, và thông tin này được sử dụng để xác định các thao tác cần làm khi phương thức SaveChanges được gọi. Lấy ví dụ, khi bạn truyền một đối tượng vào cho phương thức Add, trạng thái của nó sẽ là Added. Sau đó nếu bạn gọi SaveChanges, câu lệnh INSERT sẽ được sử dụng.</p>
<p>Một thực thể có thể mang một trong những trạng thái sau:</p>
<ul>
<li><code>Added</code>. Thực thể chưa tồn tại trong CSDL. Phương thức SaveChanges sẽ tạo ra phát biểu INSERT.</li>
<li><code>Unchanged</code>. Không cần làm gì với thực thể mang trạng thái này. Khi đọc từ CSDL, thực thể sẽ mang trạng thái này.</li>
<li><code>Modified</code>. Đã bị thay đổi, SaveChanges sẽ tạo ra câu lệnh UPDATE.</li>
<li><code>Deleted</code>. Thực thể đã được đánh dấu xóa. SaveChanges sẽ tạo ra câu lệnh DELETE.</li>
<li><code>Detached</code>. The entity isn&#8217;t being tracked by the database context. Thực thể hiện không bị quản lý bởi database context.</li>
</ul>
<p>Trong một ứng dụng desktop, trạng thái của các đối tượng được đặt tự động. Trong kiểu ứng dụng này, bạn sẽ đọc một thực thể và tạo thay đổi đến một vài thuộc tính của nó. Điều này làm cho trạng thái của nó thay đổi thành Modified. Sau đó khi gọi SaveChanges, Entity Framework sẽ tạo nên câu lệnh UPDATE để cập nhật các thuộc tính mà bạn thay đổi.</p>
<p>Tuy nhiên trong một ứng dụng web, quá trình này bị ngắt quãng vì đối tượng database context bị giải phóng sau khi tạo xong trang web. Khi phương thức action được gọi, nó sẽ tạo ra một request mới và bạn có một instance mới của đối tượng database context, do vậy bạn phải đặt lại bằng tay trạng thái của thực thể thành Modified. Sau đó khi gọi SaveChanges, Entity Framework sẽ cập nhật lại tất cả các cột của dòng tương ứng trong CSDL, bởi vì đối tượng context không có cách nào để biết thuộc tính nào đã bị thay đổi.</p>
<p>Nếu bạn muốn câu lệnh SQL UPDATE chỉ cập nhật lại các trường đã bị thay đổi, bạn có thể lưu lại giá trị gốc bằng cách nào đó (như dùng hidden) và lấy các giá trị đó khi [HttpPost] Edit được gọi. Sau đó bạn tạo một thực thể Student mới với các giá trị gốc, rồi gọi phương thức Attach trên đối tượng đó, cập nhật các giá trị mới và gọi SaveChanges(). Để có thêm thông tin, bạn có thể xem các bài viết <a href="http://blogs.msdn.com/b/adonet/archive/2011/01/29/using-dbcontext-in-ef-feature-ctp5-part-4-add-attach-and-entity-states.aspx">Add/Attach and Entity States</a> và <a href="http://blogs.msdn.com/b/adonet/archive/2011/02/01/using-dbcontext-in-ef-feature-ctp5-part-7-local-data.aspx">Local Data</a> trên blog của nhóm Entity Framework.</p>
<p>Đoạn lệnh trong <em>Views\Student\Edit.cshtml</em> tương tự như cái bạn thấy trong <em>Create.cshtml</em>, và không có thay đổi gì khác.</p>
<p>Chạy trang và bằng cách chọn tab <strong>Students</strong> tab và click lên một liên kết <strong>Edit</strong>.</p>
<p><img src="http://www.asp.net/media/897180/Windows-Live-Writer_0b3cfafc47ec_B5A4_Student_Edit_page_1.png" alt="Student_Edit_page" width="636" height="762" border="0" /></p>
<p>Thử thay đổi dữ liệu và nhấn Save. Bạn sẽ thấy dữ liệu đã thay đổi lại trên trang Index.</p>
<p><img src="http://www.asp.net/media/897185/Windows-Live-Writer_0b3cfafc47ec_B5A4_Students_Index_page_after_edit.png" alt="Students_Index_page_after_edit" width="647" height="762" border="0" /></p>
<h2>Tạo trang xóa dữ liệu</h2>
<p>Trong <em>Controllers\StudentController.cs</em>, đoạn code sinh ra trong phương thức <code>HttpGet</code> <code>Delete</code> dùng <code>Find</code> để lấy về thực thể <code>Student</code> được chọn, như bạn thấy trong <code>Details</code> và <code>Edit</code>. Tuy nhiên, để tạo một thông báo lỗi khi lời gọi SaveChanges thất bại, bạn sẽ thêm một vài tính năng vào phương thức này và view tương ứng của nó.</p>
<p>Như bạn thấy trong các thao tác tạo và cập nhật, các phương thức xóa cũng yêu cầu hai phương thức action. Phương thức dùng để phản hồi lại yêu cầu GET hiển thị một view cho phép người dùng xác nhận lại thao tác xóa, nếu người dùng chấp nhận, một yêu cầu POST sẽ được tạo. Khi điều này xảy ra, phương thức HttpPost Delete được gọi và dữ liệu khi đó mới thực sự bị xóa.</p>
<p>Bạn sẽ thêm một khối try-catch vào phương thức HttpPost Delete để bắt các lỗi có thể xảy ra khi cập nhật CSDL. Nếu lỗi xảy ra, phương thức HttpPost Delete gọi HttpGet Delete, truyền tham số cho nó để chỉ ra rằng đã có lỗi xảy ra. Phương thức HttpGet Delete sau đó sẽ hiển thị lại trang xác nhận cùng với thông báo lỗi, cho phép người dùng hủy bỏ yêu cầu hay thử lại một lần nữa.</p>
<p>Thay thế phương thức HttpGet Delete với đoạn lệnh sau, cho phép quản lý việc hiển thị thông báo lỗi:</p>
<pre>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.";
    }
    return View(db.Students.Find(id));
}</pre>
<p>Đoạn lệnh trên nhận thêm vào một tham số tùy chọn kiểu boolean chỉ ra nó có phải được gọi sau một lệnh lưu dữ liệu thất bại. Tham số này sẽ là null (hoặc false) khi HttpGet Delete được gọi để phản hồi một yêu cầu bình thường. Khi nó được gọi bởi HttpPost Delete để phản hồi một lỗi cập nhật, tham số này sẽ là true và một thông báo lỗi sẽ được chuyển đến cho view tương ứng.</p>
<p>Thay thế phương thức HttpPost Delete (đổi tên thành<code> DeleteConfirmed</code>) với đoạn lệnh sau, nó cho phép thực hiện thao tác xóa và bắt các lỗi cập nhật CSDL.</p>
<pre>[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirmed(int id)
{
    try
    {
        Student student = db.Students.Find(id);
        db.Students.Remove(student);
        db.SaveChanges();
    }
    catch (DataException)
    {
        //Log the error (add a variable name after DataException)
        return RedirectToAction("Delete",
            new System.Web.Routing.RouteValueDictionary {
                { "id", id },
                { "saveChangesError", true } });
    }
    return RedirectToAction("Index");
}</pre>
<p>This code retrieves the selected entity, then calls the <code>Remove</code> method to set the entity&#8217;s status to <code>Deleted</code>. When <code>SaveChanges</code> is called, a SQL <code>DELETE</code> command is generated.</p>
<p>Đoạn lệnh trên lấy về thực thể được chọn, sau đó gọi phương thức Remove để đặt trạng thái của thực để về Deleted. Khi SaveChanges được gọi, một câu SQL DELETE sẽ được sinh ra và thực thi.</p>
<p>Nếu muốn nâng cao hiệu năng khi ứng dụng phải xử lý khối lượng lớn dữ liệu, bạn có thể tránh việc thực thi câu SQL để lấy về dòng dữ liệu cần xóa bằng cách thay thể các đoạn lệnh gọi Find và Remove bằng đoạn lệnh sau:</p>
<pre>Student studentToDelete = new Student() { StudentID = id };
db.Entry(studentToDelete).State = EntityState.Deleted;</pre>
<p>Đoạn lệnh trên khởi tạo một thực thể Student với duy nhất khóa chính và đặt trạng thái của nó về Deleted. Đó là tất cả những gì Entity Framework cần để xóa thực thể.</p>
<p>Như đã nói đến, phương thức HttpGet Delete không thực hiện việc xóa dữ liệu. Thực hiện một thao tác xóa trong một phản hồi đến một yêu cầu dạng GET (hay sửa, tạo hoặc bất cứ thao tác nào làm thay đổi dữ liệu) có thể mang những rủi ro về bảo mật. Để có thêm thông tin, xin hãy đọc bài <a href="http://stephenwalther.com/blog/archive/2009/01/21/asp.net-mvc-tip-46-ndash-donrsquot-use-delete-links-because.aspx">ASP.NET MVC Tip #46 — Don&#8217;t use Delete Links because they create Security Holes</a> trên blog của Stephen Walther.</p>
<p>Trong <em>Views\Student\Delete.cshtml</em>, thêm đoạn lệnh sau vào giữa h2 và h3:</p>
<pre>&lt;p class="error"&gt;@ViewBag.ErrorMessage&lt;/p&gt;</pre>
<p>Chạy trang bằng cách chọn tab <strong>Students</strong> và nhấn một liên kết <strong>Delete</strong>:</p>
<p><img src="http://www.asp.net/media/897190/Windows-Live-Writer_0b3cfafc47ec_B5A4_Student_Delete_page.png" alt="Student_Delete_page" width="647" height="759" border="0" /></p>
<p>Nhấn Delete. Trang Index sẽ hiển thị lại mà không có sinh viên đã bị xóa (Bạn sẽ thấy một ví dụ về việc bắt lỗi trong bài <a href="http://www.asp.net/entity-framework/tutorials/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application">Handling Concurrency</a> cũng thuộc loạt bài này).</p>
<h2>Đảm bảo rằng kết nối đến CSDL đã được đóng</h2>
<p>Để đảm bảo các kết nối đến CSDL đã được đóng và tài nguyên do chúng chiếm giữ đã được giải phóng, bạn phải đảm bảo đối tượng context phải bị hủy. Đó là vì sao chúng ta sửa lại phương thức Dispose ở cuối lớp StudentController trong file StudentController.cs, như bạn thấy trong ví dụ dưới đây:</p>
<pre>protected override void Dispose(bool disposing)
{
    db.Dispose();
    base.Dispose(disposing);
}</pre>
<p>Lớp Controller cơ sở đã implement IDisposable, do vậy đoạn code này đơn giản thêm một phương thức override lại<code> Dispose(bool)</code> để thực hiện việc giải phóng đối tượng context.</p>
<p>Giờ bạn đã có đầy đủ các trang để thực hiện các thao tác cập nhật, thêm mới và xóa các thực thể Student. Trong bài tiếp theo bạn sẽ mở rộng chức năng của trang Index bằng việc thêm vào các tính năng sắp xếp và phân trang.</p>
<p>Các liên kết đến Entity Framework có thể được tìm thấy trong bài cuối của loạt bài này.</p>
<p>Người dịch: Đào Hải Nam</p>
<p>Bài gốc: <a href="http://www.asp.net/entity-framework/tutorials/implementing-basic-crud-functionality-with-the-entity-framework-in-asp-net-mvc-application">http://www.asp.net/entity-framework/tutorials/implementing-basic-crud-functionality-with-the-entity-framework-in-asp-net-mvc-application</a></p>
<br /> Tagged: <a href='http://namdh.wordpress.com/tag/net/'>.net</a>, <a href='http://namdh.wordpress.com/tag/getting-started-with-ef-using-mvc/'>Getting Started with EF using MVC</a>, <a href='http://namdh.wordpress.com/tag/mvc/'>mvc</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/namdh.wordpress.com/1514/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/namdh.wordpress.com/1514/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/namdh.wordpress.com/1514/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/namdh.wordpress.com/1514/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/namdh.wordpress.com/1514/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/namdh.wordpress.com/1514/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/namdh.wordpress.com/1514/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/namdh.wordpress.com/1514/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/namdh.wordpress.com/1514/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/namdh.wordpress.com/1514/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/namdh.wordpress.com/1514/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/namdh.wordpress.com/1514/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/namdh.wordpress.com/1514/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/namdh.wordpress.com/1514/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=namdh.wordpress.com&amp;blog=4017103&amp;post=1514&amp;subd=namdh&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://namdh.wordpress.com/2011/07/22/implementing-basic-crud-functionality-with-the-entity-framework-in-asp-net-mvc-application/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">namdh</media:title>
		</media:content>

		<media:content url="http://www.asp.net/media/897140/Windows-Live-Writer_0b3cfafc47ec_B5A4_Student_Details_page.png" medium="image">
			<media:title type="html">Student_Details_page</media:title>
		</media:content>

		<media:content url="http://www.asp.net/media/897145/Windows-Live-Writer_0b3cfafc47ec_B5A4_Student_Edit_page.png" medium="image">
			<media:title type="html">Student_Edit_page</media:title>
		</media:content>

		<media:content url="http://www.asp.net/media/897150/Windows-Live-Writer_0b3cfafc47ec_B5A4_Student_Create_page.png" medium="image">
			<media:title type="html">Student_Create_page</media:title>
		</media:content>

		<media:content url="http://www.asp.net/media/897155/Windows-Live-Writer_0b3cfafc47ec_B5A4_Student_delete_page.png" medium="image">
			<media:title type="html">Student_delete_page</media:title>
		</media:content>

		<media:content url="http://www.asp.net/media/897160/Windows-Live-Writer_0b3cfafc47ec_B5A4_Student_Details_page_1.png" medium="image">
			<media:title type="html">Student_Details_page</media:title>
		</media:content>

		<media:content url="http://www.asp.net/media/897165/Windows-Live-Writer_0b3cfafc47ec_B5A4_Student_Create_page_1.png" medium="image">
			<media:title type="html">Student_Create_page</media:title>
		</media:content>

		<media:content url="http://www.asp.net/media/897170/Windows-Live-Writer_0b3cfafc47ec_B5A4_Students_Create_page_error_message.png" medium="image">
			<media:title type="html">Students_Create_page_error_message</media:title>
		</media:content>

		<media:content url="http://www.asp.net/media/897175/Windows-Live-Writer_0b3cfafc47ec_B5A4_Students_Index_page_with_new_student.png" medium="image">
			<media:title type="html">Students_Index_page_with_new_student</media:title>
		</media:content>

		<media:content url="http://www.asp.net/media/897180/Windows-Live-Writer_0b3cfafc47ec_B5A4_Student_Edit_page_1.png" medium="image">
			<media:title type="html">Student_Edit_page</media:title>
		</media:content>

		<media:content url="http://www.asp.net/media/897185/Windows-Live-Writer_0b3cfafc47ec_B5A4_Students_Index_page_after_edit.png" medium="image">
			<media:title type="html">Students_Index_page_after_edit</media:title>
		</media:content>

		<media:content url="http://www.asp.net/media/897190/Windows-Live-Writer_0b3cfafc47ec_B5A4_Student_Delete_page.png" medium="image">
			<media:title type="html">Student_Delete_page</media:title>
		</media:content>
	</item>
		<item>
		<title>Tạo một mô hình dữ liệu Entity Framework cho ứng dụng ASP.NET MVC</title>
		<link>http://namdh.wordpress.com/2011/06/14/creating-an-entity-framework-mvc-1/</link>
		<comments>http://namdh.wordpress.com/2011/06/14/creating-an-entity-framework-mvc-1/#comments</comments>
		<pubDate>Tue, 14 Jun 2011 04:19:08 +0000</pubDate>
		<dc:creator>namdh</dc:creator>
				<category><![CDATA[Microsoft .NET]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[Entity Framework]]></category>
		<category><![CDATA[Getting Started with EF using MVC]]></category>

		<guid isPermaLink="false">http://namdh.wordpress.com/?p=1451</guid>
		<description><![CDATA[Ứng dụng web của trường đại học Contoso biểu diễn cách tạo ra một ứng dụng ASP.NET MVC dùng Entity Framework. Ứng dụng mẫu là website của trường đại học Contoso (trường đại học này chỉ là hư cấu &#8211; không có thật). Nó bao gồm các chức năng như đăng ký nhập học, tạo [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=namdh.wordpress.com&amp;blog=4017103&amp;post=1451&amp;subd=namdh&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Ứng dụng web của trường đại học Contoso biểu diễn cách tạo ra một ứng dụng ASP.NET MVC dùng Entity Framework. Ứng dụng mẫu là website của trường đại học Contoso (trường đại học này chỉ là hư cấu &#8211; không có thật). Nó bao gồm các chức năng như đăng ký nhập học, tạo khóa học, và phân lớp cho giảng viên. Loại bài này sẽ hướng dẫn các bước để xây dựng nên ứng dụng Contoso University. Bạn có thể <a href="http://go.microsoft.com/fwlink/?LinkId=215669">tải về ứng dụng hoàn chỉnh</a> hoặc tạo mới bằng cách theo các bước hướng dẫn trong bài. Các ví dụ được trình bày bằng C#, mã ứng dụng để có thể tải về được viết bằng C# và VB. Nếu có câu hỏi nào không liên quan trực tiếp đến loại bài này, bạn có thể gửi lên <a href="http://forums.asp.net/1227.aspx">ASP.NET Entity Framework forum</a> hay <a href="http://social.msdn.microsoft.com/forums/en-US/adodotnetentityframework/threads/">Entity Framework and LINQ to Entities forum</a>. Chúng tôi sẽ coi như bạn đã biết cách làm việc với ASP.NET MVC trong Visual Studio, nếu chưa, bạn có thể tham khảo <a href="http://www.asp.net/mvc/tutorials/getting-started-with-MVC3-part1-cs">basic ASP.NET MVC Tutorial</a>. Nếu bạn định dùng WebForm, xem loại bài <a href="http://www.asp.net/entity-framework/tutorials#Getting%20Started">Getting Started with the Entity Framework</a> và <a href="http://www.asp.net/entity-framework/tutorials#Continuing">Continuing with the Entity Framework</a>. Trước khi bắt đầu, hãy kiểm tra và đảm bảo rằng các thành phần sau đã được cài đặt:</p>
<ul>
<li><a href="http://www.microsoft.com/web/gallery/install.aspx?appsxml=&amp;appid=VS2010SP1Pack">Visual Studio 2010 SP1</a> hay <a href="http://www.microsoft.com/web/gallery/install.aspx?appsxml=&amp;appid=VWD2010SP1Pack">Visual Web Developer Express 2010 SP1</a> (Nếu bạn dùng một trong hai liên kết này, các thành phần sau cũng sẽ được cài đặt tự động).</li>
<li><a href="http://www.microsoft.com/web/gallery/install.aspx?appid=MVC3">ASP.NET MVC 3 Tools Update</a></li>
<li><a href="http://www.microsoft.com/web/gallery/install.aspx?appid=SQLCE">Microsoft SQL Server Compact 4.0</a></li>
<li><a href="http://www.microsoft.com/web/gallery/install.aspx?appid=SQLCEVSTools">Microsoft Visual Studio 2010 SP1 Tools for SQL Server Compact 4.0</a></li>
</ul>
<p><span id="more-1451"></span></p>
<h2>Ứng dụng Web Contoso University</h2>
<p>Ứng dụng bạn xây dựng sau khi hoàn thành loại bài này sẽ là một website trường đại học đơn giản.</p>
<p><img title="Contoso_University_home_page" src="http://aspnet13.orcsweb.com/media/897017/Windows-Live-Writer_75eacc89fb20_B51C_Contoso_University_home_page.png" alt="Contoso_University_home_page" width="633" height="473" border="0" /></p>
<p>Người dùng có thể xem và cập nhật thông tin sinh viên, môn học và giản viên. Một vài màn hình bạn sẽ tạo được hiển thị dưới đây:</p>
<p><img title="Students_Index_page" src="http://aspnet13.orcsweb.com/media/897022/Windows-Live-Writer_75eacc89fb20_B51C_Students_Index_page.png" alt="Students_Index_page" width="650" height="740" border="0" /></p>
<p><img title="Students_Create_page" src="http://aspnet13.orcsweb.com/media/897027/Windows-Live-Writer_75eacc89fb20_B51C_Students_Create_page.png" alt="Students_Create_page" width="650" height="797" border="0" /></p>
<p><img title="Instructors_index_page" src="http://aspnet13.orcsweb.com/media/897032/Windows-Live-Writer_75eacc89fb20_B51C_Instructors_index_page_4.png" alt="Instructors_index_page" width="653" height="750" border="0" /></p>
<p>Định dạng hiển thị được giữ giống với cái được tạo tự động bởi mẫu có trong Visual Studio, do vậy loại bài này sẽ chủ yếu tập trung vào cách sử dụng Entity Framework.</p>
<h2>Các cách tiếp cận trong lập trình với Entity Framework</h2>
<p>Như bạn thấy trong hình vẽ sau, có ba cách bạn có thể làm việc với dữ liệu trong Entity Framework<em>: <em>Database First</em>, <em>Model First</em>, và <em>Code First.</em><br />
</em></p>
<p><em><br />
</em></p>
<p><img title="Development_approaches_diagram" src="http://aspnet13.orcsweb.com/media/897037/Windows-Live-Writer_75eacc89fb20_B51C_Development_approaches_diagram_8c9f576c-ca82-4843-9177-c9fc84ea9bbb.png" alt="Development_approaches_diagram" width="491" height="523" border="0" /></p>
<h3>Database First</h3>
<p>Nếu đã có sẵn một cơ sở dữ liệu (CSDL), Entity Framework có thể tự động tạo ra một mô hình dữ liệu bao gồm các lớp và thuộc tính tương ứng với các đối tượng CSDL như bảng và cột. Thông tin về cấu trúc CSDL của bạn(<em>store schema</em>), mô hình dữ liệu (<em>conceptual model</em>), và việc ánh xạ giữa chúng được lưu dưới dạng XML trong file .edmx. Visual Studio cung cấp một trình thiết kế Entity Framework, là một trình thiết kế dạng đồ họa cho phép bạn dùng để hiển thị và chỉnh sửa file .edmx. Các bài <a href="http://www.asp.net/entity-framework/tutorials#Getting%20Started">Getting Started With the Entity Framework</a> và <a href="http://www.asp.net/entity-framework/tutorials#Continuing">Continuing With the Entity Framework</a> trong loạt bài &#8220;Sử dụng Entity Framework với Web Forms&#8221; dùng Database First.</p>
<h3>Model First</h3>
<p>Nếu hiện bạn chưa có sẵn một CSDL, bạn có thể bắt đầu bằng cách tạo một mô hình dùng trình thiết kế Entity Framework trong Visual Studio. Sau khi hoàn thành, trình thiết kế này có thể tạo ra các câu lện DDL(<em>data definition language</em>) để tạo nên CSDL. Cách tiếp cận này cũng dùng file .edmx để lưu thông tin mô hình và ánh xạ (mapping). Loạt bài <a href="http://www.asp.net/entity-framework/tutorials/what-s-new-in-the-entity-framework-4">What&#8217;s New in the Entity Framework 4</a> có một ví dụ về việc dùng cách phát triển Model First.</p>
<h3>Code First</h3>
<p>Không phụ thuộc vào việc đã có CSDL hay chưa, bạn có thể viết các lớp của riêng bạn và các thuộc tính tương ứng với các bảng và các cột, sau đó dùng chúng với Entity Framework mà không cần tới file .edmx. Đó lý vì sao đôi khi bạn thấy cách tiếp cận này được gọi là <em>Code Only</em>. mặc dù tên chính thức của nó là <em>Code First</em>. Việc ánh xạ giữa cấu trúc lưu trữ và mô hình khái niệm biểu diễn trong code của bạn được quản lý với những quy ước và tập API đặc biệt cho trước. Nếu bạn chưa có một CSDL, Entity Frame có thể tạo ra cho bạn, và thậm chí xóa và tạo lại nếu cấu trúc bị thay đổi. Loạt bài này sẽ dùng cách phát triển Code First.</p>
<p>Tập API cho việc truy cập dữ liệu trong Code First được dựa trên lớp DbClass. Tập API này cũng được dùng với Database First và Model First. Để có thông tin xem thêm bài <a href="http://blogs.msdn.com/b/adonet/archive/2011/03/07/when-is-code-first-not-code-first.aspx">When is Code First not code first?</a> trên blog của nhóm Entity Framework.</p>
<h2>POCO (Plain Old CLR Objects)</h2>
<p>Mặc nhiên, khi dùng cách tiếp cận Database First hay Model First, các lớp thực thể trong mô hình dữ liệu sẽ thừa kế từ lớp EntityObject, lớp này sẽ cung cấp các chức năng Enity Framework. Điều này có nghĩa là các lớp đó về mặt kỹ thuật không <a href="http://msdn.microsoft.com/en-us/magazine/dd882510.aspx#id0420053">persistence ignorant</a>, và do vậy chúng không đáp ứng đầy đủ các yêu cầu của thiết kế <a href="http://msdn.microsoft.com/en-us/magazine/dd419654.aspx">domain-driven</a> (nôm na là các lớp này thừa kế từ các lớp khác nên không tập trung duy nhất vào việc giải quyết yêu cầu bài toán). Các cách tiếp cận của EF cũng có thể làm việc được với POCO (<em>plain old CLR objects</em>), tức đáp ứng được persistence-ignorant bởi vì chúng không thừa kế từ lớp EntityObject. Trong loạt bài này chúng ta sẽ dùng các lớp POCO.</p>
<h2>Tạo một ứng dụng Web MVC</h2>
<p>Trước khi bắt đầu, hãy chắc chắn là các phần mềm sau đã được cài đặt lên máy tính của bạn:</p>
<ul>
<li><a href="http://www.microsoft.com/web/gallery/install.aspx?appsxml=&amp;appid=VS2010SP1Pack">Visual Studio 2010 SP1</a> hoặc <a href="http://www.microsoft.com/web/gallery/install.aspx?appsxml=&amp;appid=VWD2010SP1Pack">Visual Web Developer Express 2010 SP1</a> (Nếu bạn dùng một trong các link trên, các thành phần tiếp theo sau đây cũng sẽ được cài đặt tự động)</li>
<li><a href="http://www.microsoft.com/web/gallery/install.aspx?appid=MVC3">ASP.NET MVC 3 Tools Update</a></li>
<li><a href="http://www.microsoft.com/web/gallery/install.aspx?appid=SQLCE">Microsoft SQL Server Compact 4.0</a></li>
<li><a href="http://www.microsoft.com/web/gallery/install.aspx?appid=SQLCEVSTools">Microsoft Visual Studio 2010 SP1 Tools for SQL Server Compact 4.0</a></li>
</ul>
<p>Mở Visual Studio và tạo một project có tên &#8220;ContosoUniversity&#8221; dùng <strong>ASP.NET MVC 3 Web Application</strong>:</p>
<p><img title="New_project_dialog_box" src="http://aspnet13.orcsweb.com/media/897042/Windows-Live-Writer_75eacc89fb20_B51C_New_project_dialog_box_ff18ebb9-6aa9-4afd-93e9-af15d5b774b0.png" alt="New_project_dialog_box" width="650" height="500" border="0" /></p>
<p>Trong hộp thoại <strong>New ASP.NET MVC 3 Project</strong> chọn <strong>Internet Application</strong> và <strong>Razor</strong> view engine, xóa ô <strong>Create a unit test project</strong>, rồi nhấn <strong>OK</strong>.</p>
<p><img title="Project_template_options" src="http://aspnet13.orcsweb.com/media/897047/Windows-Live-Writer_75eacc89fb20_B51C_Project_template_options_667f6b0d-8e57-42b9-acc9-11e77a9c9ade.png" alt="Project_template_options" width="650" height="628" border="0" /></p>
<h3>Thiết đặt site style</h3>
<p>Một số thay đổi nhỏ để thiết đặt menu, layout và trang chủ.</p>
<p>Để thiết đặt menu Contoso University, trong file <em>Views\Shared\_Layout.cshtml</em>, thay thế nội dung bên trong đoạn tiêu đề h1 và các liên kết trong menu, giống như ví dụ dưới đây:</p>
<pre><span style="color:#008000;">&lt;!DOCTYPE html&gt;</span>
<span style="color:#008000;">&lt;html&gt;</span>
<span style="color:#008000;">&lt;head&gt;</span>
<span style="color:#008000;">    &lt;title&gt;@ViewBag.Title&lt;/title&gt;</span>
<span style="color:#008000;">    &lt;link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" /&gt;</span>
<span style="color:#008000;">    &lt;script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"&gt;&lt;/script&gt;</span>
<span style="color:#008000;">&lt;/head&gt;</span>
<span style="color:#008000;">&lt;body&gt;</span>
<span style="color:#008000;">    &lt;div class="page"&gt;</span>
<span style="color:#008000;">       &lt;div id="header"&gt;</span>
<span style="color:#008000;">            &lt;div id="title"&gt;</span>
<span style="color:#008000;">                &lt;h1&gt;Contoso University&lt;/h1&gt;</span>
<span style="color:#008000;">            &lt;/div&gt;</span>

<span style="color:#008000;">            &lt;div id="logindisplay"&gt;</span>
<span style="color:#008000;">                @Html.Partial("_LogOnPartial")</span>
<span style="color:#008000;">            &lt;/div&gt;</span>
<span style="color:#008000;">            &lt;div id="menucontainer"&gt;</span>
<span style="color:#008000;">                &lt;ul id="menu"&gt;</span>
<span style="color:#008000;">                    &lt;li&gt;@Html.ActionLink("Home", "Index", "Home")&lt;/li&gt;</span>
<span style="color:#008000;">                    &lt;li&gt;@Html.ActionLink("About", "About", "Home")&lt;/li&gt;</span>
<span style="color:#008000;">                    &lt;li&gt;@Html.ActionLink("Students", "Index", "Student")&lt;/li&gt;</span>
<span style="color:#008000;">                    &lt;li&gt;@Html.ActionLink("Courses", "Index", "Course")&lt;/li&gt;</span>
<span style="color:#008000;">                    &lt;li&gt;@Html.ActionLink("Instructors", "Index", "Instructor")&lt;/li&gt;</span>
<span style="color:#008000;">                    &lt;li&gt;@Html.ActionLink("Departments", "Index", "Department")&lt;/li&gt;</span>
<span style="color:#008000;">                &lt;/ul&gt;</span>
<span style="color:#008000;">            &lt;/div&gt;</span>
<span style="color:#008000;">        &lt;/div&gt;</span>
<span style="color:#008000;">        &lt;div id="main"&gt;</span>
<span style="color:#008000;">            @RenderBody()</span>
<span style="color:#008000;">        &lt;/div&gt;</span>
<span style="color:#008000;">        &lt;div id="footer"&gt;</span>
<span style="color:#008000;">        &lt;/div&gt;</span>
<span style="color:#008000;">    &lt;/div&gt;</span>
<span style="color:#008000;">&lt;/body&gt;</span>
<span style="color:#008000;">&lt;/html&gt;</span></pre>
<p>Trong file <em>Views\Home\Index.cshtml</em>, xóa tất cả mọi thứ dưới phần tiêu đề h2.</p>
<p>Trong <em>file Controllers\HomeController.cs</em>, thay thế &#8220;Welcome to ASP.NET MVC!&#8221; với &#8220;Welcome to Contoso University!&#8221;</p>
<p>Trong file <em>Content\Site.css</em>, thay đổi như sau để chuyển các tab trên menu sang trái:</p>
<ul>
<li>
<pre>Trong định nghĩa cho main <code>#main</code>, thêm <code>clear: both;</code>, giống như ví dụ dưới đây:
 <span style="color:#008000;">#main</span>
<span style="color:#008000;"> {</span>
<span style="color:#008000;">     clear: both;</span>
<span style="color:#008000;">     padding: 30px 30px 15px 30px;</span>
<span style="color:#008000;">     background-color: #fff;</span>
<span style="color:#008000;">     border-radius: 4px 0 0 0;</span>
<span style="color:#008000;">     -webkit-border-radius: 4px 0 0 0;</span>
<span style="color:#008000;">     -moz-border-radius: 4px 0 0 0;</span>
<span style="color:#008000;"> }</span></pre>
</li>
<li>
<pre>Trong định nghĩa cho <code>nav</code> và <code>#menucontainer</code>, thêm <code>clear: both; float: left;,như ví dụ dưới đây</code>:nav,
<span style="color:#008000;">#menucontainer {</span>
<span style="color:#008000;">    margin-top: 40px;</span>
<span style="color:#008000;">    clear: both;</span>
<span style="color:#008000;">    float: left;</span>
<span style="color:#008000;">}</span></pre>
</li>
</ul>
<p>Chạy thử. Bạn sẽ thấy trang chủ với menu chính.</p>
<p><img title="Contoso_University_home_page" src="http://aspnet13.orcsweb.com/media/897052/Windows-Live-Writer_75eacc89fb20_B51C_Contoso_University_home_page_1.png" alt="Contoso_University_home_page" width="633" height="473" border="0" /></p>
<h2>Tạo mô hình dữ liệu</h2>
<p>Tiếp theo bạn tạo các lớp thực thể đầu tiên cho ứng dụng Contoso University. Bạn sẽ bắt đầu với ba thực thể sau:</p>
<p><img title="Class_diagram" src="http://aspnet13.orcsweb.com/media/897057/Windows-Live-Writer_75eacc89fb20_B51C_Class_diagram.png" alt="Class_diagram" width="600" height="447" border="0" /></p>
<p>Có một mối quan hệ một nhiều giữa Student và Enrollment, và một quan hệ một nhiểu giữa Course và Enrollment. Nói cách khác, một sinh viên có thể tham gia nhiều khóa học, và một khóa học lại có thể có nhiều sinh viên tham gia.</p>
<p>Trong phần tiếp theo, bạn sẽ tạo một cho mỗi thực thể trên.</p>
<div>
<p><strong>Ghi chú</strong> Nếu thử chạy project trước khi hoàn thành việc tạo tất cả các lớp thực thể, bạn sẽ bị lỗi dịch chương trình.</p>
</div>
<h3>Thực thể Student</h3>
<p><img title="Student_entity" src="http://aspnet13.orcsweb.com/media/897062/Windows-Live-Writer_75eacc89fb20_B51C_Student_entity_d3e525a4-b62b-4257-8cf8-7170fb57dd34.png" alt="Student_entity" width="282" height="203" border="0" /></p>
<p>Trong thư mục Model, tạo một file Student.cs và thay thế nội dung với đoạn lệnh sau:</p>
<pre><span style="color:#008000;">using System;</span>
<span style="color:#008000;">using System.Collections.Generic;</span>

<span style="color:#008000;">namespace ContosoUniversity.Models</span>
<span style="color:#008000;">{</span>
<span style="color:#008000;">    public class Student</span>
<span style="color:#008000;">    {</span>
<span style="color:#008000;">        public int StudentID { get; set; }</span>
<span style="color:#008000;">        public string LastName { get; set; }</span>
<span style="color:#008000;">        public string FirstMidName { get; set; }</span>
<span style="color:#008000;">        public DateTime EnrollmentDate { get; set; }</span>
<span style="color:#008000;">        public virtual ICollection&lt;Enrollment&gt; Enrollments { get; set; }</span>
<span style="color:#008000;">    }</span>
<span style="color:#008000;">}</span></pre>
<p>Thuộc tính StudentID sẽ trở nên cột khóa chính của bảng tương ứng với lớp này trong CSDL. Mặc nhiên, EF diễn dịch một thuộc tính có tên ID hay TênlớpID như khóa chính.</p>
<p>Enrollment là một thuộc tính <em>navigation. </em>Các thuộc tính navigation giữ liên hệ với các thực thể có quan hệ với thực thể này. Trong trường hợp này, thuộc tính Enrollments của thực thể Student sẽ giữ tất cả các Enrollment có liên quan đến nó. Nói cách khác, nếu cho một dòng Student trong CSDL có liên kết với 2 dòng trong bảng Enrollment (các dòng chứa khóa chính của Student trong cột khóa ngoài StudentID), thuộc tính navigation Enrollments của thực thể Student sẽ chứa 2 đối tượng Enrollment đó.</p>
<p>Các thuộc tính navigation thường được định nghĩa là virtual, do vậy chúng có thể tận dụng được một tính năng của Entity Framework là lazy loading. (Lazy loading sẽ được giải thích sau, trong bài &#8220;Đọc các dữ liệu liên quan&#8221; cũng thuộc loại bài này). Nếu một thuộc tính navigation có thể chứa nhiều thực thể khác (như trong quan hệ nhiều-nhiều hay một-nhiều), kiểu của nó phải là ICollection.</p>
<h3>Thực thể Enrollment</h3>
<p><img title="Enrollment_entity" src="http://aspnet13.orcsweb.com/media/897067/Windows-Live-Writer_75eacc89fb20_B51C_Enrollment_entity_140a15e0-c2f5-4bbd-a7a3-ca7b2f7622d5.png" alt="Enrollment_entity" width="284" height="223" border="0" /></p>
<p>Trong thư mục Models, tạo file Enrollment.cs và thay thế nội dung của nó với đoạn lệnh sau:</p>
<pre></pre>
<p><span style="color:#008000;">using System;</span><br />
<span style="color:#008000;">using System.Collections.Generic;</span></p>
<p><span style="color:#008000;">namespace ContosoUniversity.Models</span><br />
<span style="color:#008000;">{</span><br />
<span style="color:#008000;">    public class Enrollment</span><br />
<span style="color:#008000;">    {</span><br />
<span style="color:#008000;">        public int EnrollmentID { get; set; }</span><br />
<span style="color:#008000;">        public int CourseID { get; set; }</span><br />
<span style="color:#008000;">        public int StudentID { get; set; }</span><br />
<span style="color:#008000;">        public decimal? Grade { get; set; }</span><br />
<span style="color:#008000;">        public virtual Course Course { get; set; }</span><br />
<span style="color:#008000;">        public virtual Student Student { get; set; }</span><br />
<span style="color:#008000;">    }</span><br />
<span style="color:#008000;">}</span></p>
<p>Dấu chấm hỏi phía sau kiểu decimal chỉ ra Grade có thể mang giá trị null. Một Grade là null khác với việc nó bằng không &#8211; null nghĩa là Grade chưa được gán giá trị, trong khi zero nghĩa là nó đã được gán giá trị không.</p>
<p>Thuộc tính StudentID là một khóa ngoài, và thuộc tính navigation tương ứng là Student. Một Enrollment chỉ kết hợp với duy nhất một thực thể Student, do vậy thuộc tính này chỉ giữ một thực thể Student mà thôi (không giống như Student.Enrollments bạn thấy trước đây có giữ nhiều thực thể Enrollments).</p>
<p>Thuộc tính CourseID là khóa ngoài, và thuộc tính navigation tương ứng là Course. Một thực thể Enrollment kết hợp với một thực thể Student.</p>
<h3>The Course Entity</h3>
<p><img title="Course_entity" src="http://aspnet13.orcsweb.com/media/897072/Windows-Live-Writer_75eacc89fb20_B51C_Course_entity_1659670a-0ec1-4c03-964d-29c532525580.png" alt="Course_entity" width="282" height="188" border="0" /></p>
<p>Trong thư mục <em>Models</em>, tạo thêm <em>Course.cs</em> và thay thế nội dung với đoạn lệnh sau:</p>
<pre><span style="color:#008000;">using System;</span>
<span style="color:#008000;">using System.Collections.Generic;</span>

<span style="color:#008000;">namespace ContosoUniversity.Models</span>
<span style="color:#008000;">{</span>
<span style="color:#008000;">    public class Course</span>
<span style="color:#008000;">    {</span>
<span style="color:#008000;">        public int CourseID { get; set; }</span>
<span style="color:#008000;">        public string Title { get; set; }</span>
<span style="color:#008000;">        public int Credits { get; set; }</span>
<span style="color:#008000;">        public virtual ICollection&lt;Enrollment&gt; Enrollments { get; set; }</span>
<span style="color:#008000;">    }</span>
<span style="color:#008000;">}</span></pre>
<p><code>Enrollments là một</code> thuộc tính navigation. Một thực thể Course có thể quan hệ với số lượng Enrollment bất kỳ.</p>
<h2>Tạo một Database Context</h2>
<p>Lớp chịu trách nhiệm chính trong việc kết hợp các tính năng của Entity Framework với một mô hình dữ liệu được gọi là lớp Database Context. Bạn tạo lớp này bằng cách thừa kế từ <code>System.Data.Entity.DbContext</code>. Trong chương trình bạn sẽ chỉ ra thực thể nào sẽ được bao gồm trong mô hình dữ liệu. Bạn cũng có thể tùy biến lại một số tính năng của Entity Framework. Trong project này, tên lớp sẽ là SchoolContext.</p>
<p>Tạo một thư mục tên DAL, trong thư mục đó bạn tạo một lớp có tên SchoolContext và thay thế nội dung của nó với đoạn lệnh sau:</p>
<pre><span style="color:#008000;">using System;</span>
<span style="color:#008000;">using System.Collections.Generic;</span>
<span style="color:#008000;">using System.Data.Entity;</span>
<span style="color:#008000;">using ContosoUniversity.Models;</span>
<span style="color:#008000;">using System.Data.Entity.ModelConfiguration.Conventions;</span>

<span style="color:#008000;">namespace ContosoUniversity.Models</span>
<span style="color:#008000;">{</span>
<span style="color:#008000;">    public class SchoolContext : DbContext</span>
<span style="color:#008000;">    {</span>
<span style="color:#008000;">        public DbSet&lt;Student&gt; Students { get; set; }</span>
<span style="color:#008000;">        public DbSet&lt;Enrollment&gt; Enrollments { get; set; }</span>
<span style="color:#008000;">        public DbSet&lt;Course&gt; Courses { get; set; }</span>

<span style="color:#008000;">        protected override void OnModelCreating(DbModelBuilder modelBuilder)</span>
<span style="color:#008000;">        {</span>
<span style="color:#008000;">            modelBuilder.Conventions.Remove&lt;PluralizingTableNameConvention&gt;();</span>
<span style="color:#008000;">        }</span>
<span style="color:#008000;">    }</span>
<span style="color:#008000;">}</span></pre>
<p><span style="color:#008000;">Đ</span>oạn chương trình trên tạo một thuộc tính DbSet cho mỗi tập thực thể. Theo cách nói của Entity Framework, một tập thực thể đại diện cho một bảng trong CSDL và một thực thể tương ứng với một dòng trong bảng.</p>
<p>Câu lệnh trong phương thức <code>OnModelCreating</code> để tránh biến tên bảng thành dạng số nhiều. Nếu không làm vậy, tên các bảng được tạo có thể trở thành Students, Courses và Enrollments. Thay vì vậy, tên bảng sẽ là Student, Course và Enrollment. Các nhà phát triển thường không thống nhất với nhau về việc tên bảng có nên ở dạng số nhiều hay không. Trong loạt bài này, chúng ta sẽ dùng tên bảng dạng đơn, nhưng điều quan trọng là có thể lựa chọn dang tên bảng bạn muốn bằng cách thêm hoặc bỏ dòng lệnh trên.</p>
<p>(Lớp này nằm trong namespace Models, bởi vì trong một số trường hợp Code First cho rằng các lớp thực thể và lớp context trong cùng namespace).</p>
<h2>Thiết đặt chuỗi kết nối</h2>
<p>Bạn không phải tạo chuỗi kết nối, và trong trường hợp đó, Entity Framework sẽ tự động tạo một CSDL SQL Serrver Express. Tuy nhiên trong loạt bài này, bạn sẽ làm việc với CSDL SQL Server Compact, vì vậy bạn cần tạo một chuỗi kết nối để chỉ ra điều đó.</p>
<p>Mở file Web.config và thêm một chuỗi kết nối mới và tập ConnectionStrings, giống như trong ví dụ dưới đây. (Chú ý là cập nhật lại Web.config trong thư mục gốc của project, trong thư mục Views cũng có một file Web.config nhưng không cần cập nhật lại).</p>
<pre><span style="color:#008000;">&lt;add name="SchoolContext" connectionString="Data Source=|DataDirectory|School.sdf" providerName="System.Data.SqlServerCe.4.0"/&gt;</span></pre>
<p>By default, the Entity Framework looks for a connection string named the same as the object context class. The connection string you&#8217;ve added specifies a SQL Server Compact database named <em>School.sdf</em> located in the <em>App_Data</em> folder.</p>
<p>Mặc nhiên, Entity Framework tìm chuỗi kết nối có tên trùng với tên lớp context. Chuỗi kết nối bạn thêm vào chỉ đến một CSDL SQL Server Compact có tên School.sdf bên trong thư mục App_Data.</p>
<h2>Khởi tạo CSDL với dữ liệu kiểm thử</h2>
<p>Entity Framework có thể tự động tạo (hoặc xóa hay tạo lại) một CSDL cho bạn khi chạy ứng dụng. Bạn có thể yêu cầu điều này được thực hiện mỗi khi chạy ứng dụng hay chỉ khi mô hình dữ liệu không đồng bộ với CSDL. Bạn cũng có thể viết một lớp chứa một phương thức để Entity Framework tự động gọi sau khi tạo ra CSDL, điều này giúp bạn có thể đưa dữ liệu test vào CSDL một cách tự động. Trong phần này bạn sẽ chỉ ra CSDL phải được xóa và tạo lại một khi mô hình bị thay đổi.</p>
<p>Trong thư mục DAL, tạo một lớp mới có tên SchoolInitializer.cs và thay thế nội dung của nó với đoạn lệnh dưới đây, nó sẽ cho phép CSDL được tạo khi cần và nạp dữ liệu kiểm thử vào trong CSDL mới.</p>
<pre><span style="color:#008000;">using System;</span>
<span style="color:#008000;">using System.Collections.Generic;</span>
<span style="color:#008000;">using System.Linq;</span>
<span style="color:#008000;">using System.Web;</span>
<span style="color:#008000;">using System.Data.Entity;</span>
<span style="color:#008000;">using ContosoUniversity.Models;</span>

<span style="color:#008000;">namespace ContosoUniversity.DAL</span>
<span style="color:#008000;">{</span>
<span style="color:#008000;">    public class SchoolInitializer : DropCreateDatabaseIfModelChanges&lt;SchoolContext&gt;</span>
<span style="color:#008000;">    {</span>
<span style="color:#008000;">        protected override void Seed(SchoolContext context)</span>
<span style="color:#008000;">        {</span>
<span style="color:#008000;">            var students = new List&lt;Student&gt;</span>
<span style="color:#008000;">            {</span>
<span style="color:#008000;">                new Student { FirstMidName = "Carson",   LastName = "Alexander", EnrollmentDate = DateTime.Parse("2005-09-01") },</span>
<span style="color:#008000;">                new Student { FirstMidName = "Meredith", LastName = "Alonso",    EnrollmentDate = DateTime.Parse("2002-09-01") },</span>
<span style="color:#008000;">                new Student { FirstMidName = "Arturo",   LastName = "Anand",     EnrollmentDate = DateTime.Parse("2003-09-01") },</span>
<span style="color:#008000;">                new Student { FirstMidName = "Gytis",    LastName = "Barzdukas", EnrollmentDate = DateTime.Parse("2002-09-01") },</span>
<span style="color:#008000;">                new Student { FirstMidName = "Yan",      LastName = "Li",        EnrollmentDate = DateTime.Parse("2002-09-01") },</span>
<span style="color:#008000;">                new Student { FirstMidName = "Peggy",    LastName = "Justice",   EnrollmentDate = DateTime.Parse("2001-09-01") },</span>
<span style="color:#008000;">                new Student { FirstMidName = "Laura",    LastName = "Norman",    EnrollmentDate = DateTime.Parse("2003-09-01") },</span>
<span style="color:#008000;">                new Student { FirstMidName = "Nino",     LastName = "Olivetto",  EnrollmentDate = DateTime.Parse("2005-09-01") }</span>
<span style="color:#008000;">            };</span>
<span style="color:#008000;">            students.ForEach(s =&gt; context.Students.Add(s));</span>
<span style="color:#008000;">            context.SaveChanges();</span>

<span style="color:#008000;">            var courses = new List&lt;Course&gt;</span>
<span style="color:#008000;">            {</span>
<span style="color:#008000;">                new Course { Title = "Chemistry",      Credits = 3, },</span>
<span style="color:#008000;">                new Course { Title = "Microeconomics", Credits = 3, },</span>
<span style="color:#008000;">                new Course { Title = "Macroeconomics", Credits = 3, },</span>
<span style="color:#008000;">                new Course { Title = "Calculus",       Credits = 4, },</span>
<span style="color:#008000;">                new Course { Title = "Trigonometry",   Credits = 4, },</span>
<span style="color:#008000;">                new Course { Title = "Composition",    Credits = 3, },</span>
<span style="color:#008000;">                new Course { Title = "Literature",     Credits = 4, }</span>
<span style="color:#008000;">            };</span>
<span style="color:#008000;">            courses.ForEach(s =&gt; context.Courses.Add(s));</span>
<span style="color:#008000;">            context.SaveChanges();</span>

<span style="color:#008000;">            var enrollments = new List&lt;Enrollment&gt;</span>
<span style="color:#008000;">            {</span>
<span style="color:#008000;">                new Enrollment { StudentID = 1, CourseID = 1, Grade = 1 },</span>
<span style="color:#008000;">                new Enrollment { StudentID = 1, CourseID = 2, Grade = 3 },</span>
<span style="color:#008000;">                new Enrollment { StudentID = 1, CourseID = 3, Grade = 1 },</span>
<span style="color:#008000;">                new Enrollment { StudentID = 2, CourseID = 4, Grade = 2 },</span>
<span style="color:#008000;">                new Enrollment { StudentID = 2, CourseID = 5, Grade = 4 },</span>
<span style="color:#008000;">                new Enrollment { StudentID = 2, CourseID = 6, Grade = 4 },</span>
<span style="color:#008000;">                new Enrollment { StudentID = 3, CourseID = 1            },</span>
<span style="color:#008000;">                new Enrollment { StudentID = 4, CourseID = 1,           },</span>
<span style="color:#008000;">                new Enrollment { StudentID = 4, CourseID = 2, Grade = 4 },</span>
<span style="color:#008000;">                new Enrollment { StudentID = 5, CourseID = 3, Grade = 3 },</span>
<span style="color:#008000;">                new Enrollment { StudentID = 6, CourseID = 4            },</span>
<span style="color:#008000;">                new Enrollment { StudentID = 7, CourseID = 5, Grade = 2 },</span>
<span style="color:#008000;">            };</span>
<span style="color:#008000;">            enrollments.ForEach(s =&gt; context.Enrollments.Add(s));</span>
<span style="color:#008000;">            context.SaveChanges();</span>
<span style="color:#008000;">        }</span>
<span style="color:#008000;">    }</span>
<span style="color:#008000;">}</span></pre>
<p>Phương thức Seed nhận vào đối tượng context như một tham số, và đoạn code bên trong phương thức này sẽ dùng đối tượng context đó để thêm các thực thể vào CSDL. Với mỗi kiểu thực thể, đoạn lệnh sẽ tạo một tập hợp các thực thể mới, và thêm chúng vào trong thuộc tính DbSet tương ứng, sau đó lưu lại vào CSDL. Không cần thiết phải gọi SaveChanges() sau mỗi lần thêm một nhóm thực thể như chúng ta làm ở đây, nhưng làm như vậy sẽ giúp bạn xác định được lỗi trong quá trình ghi vào CSDL dễ dàng hơn.</p>
<p>Thêm các thay đổi sau vào file Global.asax.cs để các câu lệnh khởi tạo được chạy khi bắt đầu ứng dụng:</p>
<ul>
<li>Thêm các phát biểu using:
<pre><span style="color:#008000;">using System.Data.Entity; using ContosoUniversity.Models; using ContosoUniversity.DAL;</span></pre>
</li>
<li>Trong phương thức <code>Application_Start</code>, gọi đến phương thức khởi tạo CSDL Entity Framework:
<pre> <span style="color:#008000;">Database.SetInitializer&lt;SchoolContext&gt;(new SchoolInitializer());</span></pre>
</li>
</ul>
<p>Bây giờ mỗi khi chạy ứng dụng, trong lần kết nối đầu tiên đến CSDL, Entity Framework sẽ so sánh CSDL với mô hình dữ liệu của bạn (lớp SchoolContext). Nếu có sự khác nhau, ứng dụng sẽ xóa và tạo lại CSDL.</p>
<div>
<p><strong>Ghi chú:</strong> Khi đưa ứng dụng lên một máy chủ web chạy thật, bạn phải xóa các dòng lệnh nạp dữ liệu kiểm thử.</p>
</div>
<p>Giờ bạn sẽ tạo một trang web để hiển thị dữ liệu, và việc xử lý các yêu cầu dữ liệu sẽ tự động thực hiện việc tạo CSDL. Bạn sẽ bắt đầu bằng việc tạo một controller mới. Nhưng trước khi làm điều này, hãy build project để trình hỗ trợ tạo controller có thể tìm thấy được các lớp mô hình và lớp context của bạn.</p>
<h2>Tạo Student Controller</h2>
<p>Để tạo Student Controller, nhấn phải chuột lên thư mục Controllers trong cửa sổ Solution Explorer và chọn Add, sau đó chọn Controller. Trong hộp thoại Add Controller, đặt các giá trị giống như sau và nhân Add:</p>
<ul>
<li>Controller name: <strong>StudentController</strong>.</li>
<li>Template: <strong>Controller with read/write actions and views, using Entity Framework</strong>. (Mặc nhiên)</li>
<li>Model class: <strong>Student (ContosoUniversity.Models)</strong>. (Nếu không thấy mục này trong danh sách, hãy thử dịch và làm lại)</li>
<li>Data context class: <strong>SchoolContext (ContosoUniversity.Models)</strong>.</li>
<li>Views: <strong>Razor (CSHTML)</strong>. (Mặc nhiên)</li>
</ul>
<p><img title="Add_Controller_dialog_box_for_Student_controller" src="http://aspnet13.orcsweb.com/media/909272/Windows-Live-Writer_75eacc89fb20_B51C_Add_Controller_dialog_box_for_Student_controller_e8084aea-547c-491c-80f8-75816930098c.png" alt="Add_Controller_dialog_box_for_Student_controller" width="552" height="385" border="0" /></p>
<p>Mở file <em>Controllers\StudentController.cs</em>. You see a class variable has been created that instantiates a database context object: Bạn sẽ thấy một biến database context thuộc lớp đã được khai báo và khởi tạo.</p>
<pre><span style="color:#008000;">private SchoolContext db = new SchoolContext();</span></pre>
<p>Phương thức action <code>Index</code> trả về một danh sách các sinh viên từ thuộc tính Students của đối tượng database context:</p>
<pre><span style="color:#008000;"> public ViewResult Index() {     return View(db.Students.ToList()); }</span></pre>
<p>Trình hỗ trợ tạo controller cũng tạo cho bạn một tập các view cho lớp Student. Để tùy biến lại phần tiêu đề và thứ tự các cột trong view Index, mở file Views\Student\Index.cshtml và thay thế nội dung hiện có với đoạn lệnh sau:</p>
<pre><span style="color:#008000;">@model IEnumerable&lt;ContosoUniversity.Models.Student&gt;</span>

<span style="color:#008000;">@{</span>
<span style="color:#008000;">    ViewBag.Title = "Students";</span>
<span style="color:#008000;">}</span>

<span style="color:#008000;">&lt;h2&gt;Students&lt;/h2&gt;</span>

<span style="color:#008000;">&lt;p&gt;</span>
<span style="color:#008000;">    @Html.ActionLink("Create New", "Create")</span>
<span style="color:#008000;">&lt;/p&gt;</span>
<span style="color:#008000;">&lt;table&gt;</span>
<span style="color:#008000;">    &lt;tr&gt;</span>
<span style="color:#008000;">        &lt;th&gt;&lt;/th&gt;</span>
<span style="color:#008000;">        &lt;th&gt;Last Name&lt;/th&gt;</span>
<span style="color:#008000;">        &lt;th&gt;First Name&lt;/th&gt;</span>
<span style="color:#008000;">        &lt;th&gt;Enrollment Date&lt;/th&gt;</span>
<span style="color:#008000;">    &lt;/tr&gt;</span>

<span style="color:#008000;">@foreach (var item in Model) {</span>
<span style="color:#008000;">    &lt;tr&gt;</span>
<span style="color:#008000;">        &lt;td&gt;</span>
<span style="color:#008000;">            @Html.ActionLink("Edit", "Edit", new { id=item.StudentID }) |</span>
<span style="color:#008000;">            @Html.ActionLink("Details", "Details", new { id=item.StudentID }) |</span>
<span style="color:#008000;">            @Html.ActionLink("Delete", "Delete", new { id=item.StudentID })</span>
<span style="color:#008000;">        &lt;/td&gt;</span>
<span style="color:#008000;">        &lt;td&gt;</span>
<span style="color:#008000;">            @Html.DisplayFor(modelItem =&gt; item.LastName)</span>
<span style="color:#008000;">        &lt;/td&gt;</span>
<span style="color:#008000;">        &lt;td&gt;</span>
<span style="color:#008000;">            @Html.DisplayFor(modelItem =&gt; item.FirstMidName)</span>
<span style="color:#008000;">        &lt;/td&gt;</span>
<span style="color:#008000;">        &lt;td&gt;</span>
<span style="color:#008000;">            @Html.DisplayFor(modelItem =&gt; item.EnrollmentDate)</span>
<span style="color:#008000;">        &lt;/td&gt;</span>
<span style="color:#008000;">    &lt;/tr&gt;</span>
<span style="color:#008000;">}</span>

<span style="color:#008000;">&lt;/table&gt;</span></pre>
<p>Chạy web site, nhấn vào tab Students, bạn sẽ thấy một danh sách các sinh viên.</p>
<p><img title="Students_Index_page" src="http://aspnet13.orcsweb.com/media/897082/Windows-Live-Writer_75eacc89fb20_B51C_Students_Index_page_2b429096-c89f-4c08-ad16-e42c1a5abd74.png" alt="Students_Index_page" width="650" height="740" border="0" /></p>
<p>Đóng cửa sổ trình duyệt. Trong Solution Explorer, chọn project ContosoUniversity (hãy chắc chắn là bạn chọn project chứ không phải solution). Nhấn Show all Files nếu chưa ở chế độ đó. Nhấn Refresh và mở phần App_Data để nhìn thấy file Shool.sdf.</p>
<p><img title="School.sdf_file_in_Solution_Explorer" src="http://aspnet13.orcsweb.com/media/897087/Windows-Live-Writer_75eacc89fb20_B51C_School.sdf_file_in_Solution_Explorer_30905de5-b269-4bb0-8497-686a1260dc24.png" alt="School.sdf_file_in_Solution_Explorer" width="303" height="414" border="0" /></p>
<p>Nhấn đúp lên School.sdf. Sau đó mở thư mục Tables để xem các bảng đã được tạo trong CSDL.</p>
<div>
<p><strong>Ghi chú:</strong> Nếu bạn gặp lỗi khi nhấn đúp chuột lên School.sdf, hãy kiểm tra lại để đảm bảo bạn đã cài <strong>Visual Studio 2010 SP1 Tools for SQL Server Compact 4.0</strong>. (Bạn có thể xem liên kết đến phần mềm này ở đầu trang). Nếu bây giờ bạn mới cài đặt nó, bạn sẽ phải đóng và mở lại Visual Studio.<strong><br />
</strong></p>
</div>
<p><img title="Server_Explorer_showing_School_tables" src="http://aspnet13.orcsweb.com/media/897092/Windows-Live-Writer_75eacc89fb20_B51C_Server_Explorer_showing_School_tables.png" alt="Server_Explorer_showing_School_tables" width="227" height="276" border="0" /></p>
<p>Có một bảng cho mỗi tập thực thể, và thêm một bảng có tên EdmMetadata, bảng này được dùng bởi Entity Framework để xác định xem CSDL và mô hình có đồng bộ với nhau hay không.</p>
<p>Nhấn chuột phải lên một bảng và chọn Show Table Data để xem dữ liệu bên trong (được đưa vào bởi lớp SchoolInitializer).</p>
<p><img title="Table_data_in_Student_table" src="http://aspnet13.orcsweb.com/media/897097/Windows-Live-Writer_75eacc89fb20_B51C_Table_data_in_Student_table_bcec9222-b4ea-4934-8aab-3eeb820378d0.png" alt="Table_data_in_Student_table" width="515" height="308" border="0" /></p>
<p>Khi đã hoàn thành, hãy đóng kết nối lại. (Nếu không đóng, bạn có thể sẽ gặp lỗi trong lần chạy project tiếp theo).</p>
<p><img title="Close_the_SQL_Compact_connection" src="http://aspnet13.orcsweb.com/media/897102/Windows-Live-Writer_75eacc89fb20_B51C_Close_the_SQL_Compact_connection_8d2562e2-1198-425e-b170-7ff21481fdd1.png" alt="Close_the_SQL_Compact_connection" width="383" height="486" border="0" /></p>
<h2>Các quy ước</h2>
<p>Khối lượng lệnh bạn phải viết để Entity Framework đủ để tạo một CSDL hoàn chỉnh là rất ít nhờ vào một số quy ước được đặt ra bởi Entity Framework. Một số trong chúng đã được nhắc đến như là:</p>
<ul>
<li>Dạng số nhiều của tên lớp thực thể sẽ được dùng như tên bảng.</li>
<li>Tên các thuộc tính sẽ được dùng như tên cột.</li>
<li>Các thuộc tính có tên <code>ID</code> hay <em>classname</em><code>ID</code> được coi là khóa chính.</li>
<li>Entity Framework kết nối đến CSDL của bạn bằng cách tìm chuỗi kết nối có cùng tên với lớp database context. (<code>SchoolContext</code> trong trường hợp này).</li>
</ul>
<p>Bạn đã thấy các quy ước này cũng có thể bị thay đổi (ví dụ, bạn chỉ ra tên bảng không nên ở dạng số nhiều), và bạn sẽ học thêm về các quy ước cũng như cách thay thế chúng trong bài <a href="http://www.asp.net/entity-framework/tutorials/creating-a-more-complex-data-model-for-an-asp-net-mvc-application">Creating a More Complex Data Model</a> trong cùng loạt bài này.</p>
<p>Bạn đã tạo một ứng dụng đơn giản dùng ENTity Framework và SQL Server COMpact để lưu trữ và hiển thị dữ liệu. Trong phần tiếp theo bạn sẽ học các thực hiện các thao tác CRUD cơ bản (CRUD: create, read, update, delete).</p>
<p>Liên kết đến các tài nguyên khác của ENtity Framework có thể tìm thấy trong bài cuối cùng của loạt bài này.</p>
<p>Người dịch: <a href="http://www.daohainam.com"><strong>Đào Hải Nam</strong></a></p>
<p>Bài viết gốc: <a href="http://www.asp.net/entity-framework/tutorials/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application">http://www.asp.net/entity-framework/tutorials/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application</a></p>
<br /> Tagged: <a href='http://namdh.wordpress.com/tag/net/'>.net</a>, <a href='http://namdh.wordpress.com/tag/entity-framework/'>Entity Framework</a>, <a href='http://namdh.wordpress.com/tag/getting-started-with-ef-using-mvc/'>Getting Started with EF using MVC</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/namdh.wordpress.com/1451/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/namdh.wordpress.com/1451/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/namdh.wordpress.com/1451/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/namdh.wordpress.com/1451/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/namdh.wordpress.com/1451/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/namdh.wordpress.com/1451/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/namdh.wordpress.com/1451/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/namdh.wordpress.com/1451/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/namdh.wordpress.com/1451/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/namdh.wordpress.com/1451/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/namdh.wordpress.com/1451/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/namdh.wordpress.com/1451/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/namdh.wordpress.com/1451/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/namdh.wordpress.com/1451/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=namdh.wordpress.com&amp;blog=4017103&amp;post=1451&amp;subd=namdh&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://namdh.wordpress.com/2011/06/14/creating-an-entity-framework-mvc-1/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">namdh</media:title>
		</media:content>

		<media:content url="http://aspnet13.orcsweb.com/media/897017/Windows-Live-Writer_75eacc89fb20_B51C_Contoso_University_home_page.png" medium="image">
			<media:title type="html">Contoso_University_home_page</media:title>
		</media:content>

		<media:content url="http://aspnet13.orcsweb.com/media/897022/Windows-Live-Writer_75eacc89fb20_B51C_Students_Index_page.png" medium="image">
			<media:title type="html">Students_Index_page</media:title>
		</media:content>

		<media:content url="http://aspnet13.orcsweb.com/media/897027/Windows-Live-Writer_75eacc89fb20_B51C_Students_Create_page.png" medium="image">
			<media:title type="html">Students_Create_page</media:title>
		</media:content>

		<media:content url="http://aspnet13.orcsweb.com/media/897032/Windows-Live-Writer_75eacc89fb20_B51C_Instructors_index_page_4.png" medium="image">
			<media:title type="html">Instructors_index_page</media:title>
		</media:content>

		<media:content url="http://aspnet13.orcsweb.com/media/897037/Windows-Live-Writer_75eacc89fb20_B51C_Development_approaches_diagram_8c9f576c-ca82-4843-9177-c9fc84ea9bbb.png" medium="image">
			<media:title type="html">Development_approaches_diagram</media:title>
		</media:content>

		<media:content url="http://aspnet13.orcsweb.com/media/897042/Windows-Live-Writer_75eacc89fb20_B51C_New_project_dialog_box_ff18ebb9-6aa9-4afd-93e9-af15d5b774b0.png" medium="image">
			<media:title type="html">New_project_dialog_box</media:title>
		</media:content>

		<media:content url="http://aspnet13.orcsweb.com/media/897047/Windows-Live-Writer_75eacc89fb20_B51C_Project_template_options_667f6b0d-8e57-42b9-acc9-11e77a9c9ade.png" medium="image">
			<media:title type="html">Project_template_options</media:title>
		</media:content>

		<media:content url="http://aspnet13.orcsweb.com/media/897052/Windows-Live-Writer_75eacc89fb20_B51C_Contoso_University_home_page_1.png" medium="image">
			<media:title type="html">Contoso_University_home_page</media:title>
		</media:content>

		<media:content url="http://aspnet13.orcsweb.com/media/897057/Windows-Live-Writer_75eacc89fb20_B51C_Class_diagram.png" medium="image">
			<media:title type="html">Class_diagram</media:title>
		</media:content>

		<media:content url="http://aspnet13.orcsweb.com/media/897062/Windows-Live-Writer_75eacc89fb20_B51C_Student_entity_d3e525a4-b62b-4257-8cf8-7170fb57dd34.png" medium="image">
			<media:title type="html">Student_entity</media:title>
		</media:content>

		<media:content url="http://aspnet13.orcsweb.com/media/897067/Windows-Live-Writer_75eacc89fb20_B51C_Enrollment_entity_140a15e0-c2f5-4bbd-a7a3-ca7b2f7622d5.png" medium="image">
			<media:title type="html">Enrollment_entity</media:title>
		</media:content>

		<media:content url="http://aspnet13.orcsweb.com/media/897072/Windows-Live-Writer_75eacc89fb20_B51C_Course_entity_1659670a-0ec1-4c03-964d-29c532525580.png" medium="image">
			<media:title type="html">Course_entity</media:title>
		</media:content>

		<media:content url="http://aspnet13.orcsweb.com/media/909272/Windows-Live-Writer_75eacc89fb20_B51C_Add_Controller_dialog_box_for_Student_controller_e8084aea-547c-491c-80f8-75816930098c.png" medium="image">
			<media:title type="html">Add_Controller_dialog_box_for_Student_controller</media:title>
		</media:content>

		<media:content url="http://aspnet13.orcsweb.com/media/897082/Windows-Live-Writer_75eacc89fb20_B51C_Students_Index_page_2b429096-c89f-4c08-ad16-e42c1a5abd74.png" medium="image">
			<media:title type="html">Students_Index_page</media:title>
		</media:content>

		<media:content url="http://aspnet13.orcsweb.com/media/897087/Windows-Live-Writer_75eacc89fb20_B51C_School.sdf_file_in_Solution_Explorer_30905de5-b269-4bb0-8497-686a1260dc24.png" medium="image">
			<media:title type="html">School.sdf_file_in_Solution_Explorer</media:title>
		</media:content>

		<media:content url="http://aspnet13.orcsweb.com/media/897092/Windows-Live-Writer_75eacc89fb20_B51C_Server_Explorer_showing_School_tables.png" medium="image">
			<media:title type="html">Server_Explorer_showing_School_tables</media:title>
		</media:content>

		<media:content url="http://aspnet13.orcsweb.com/media/897097/Windows-Live-Writer_75eacc89fb20_B51C_Table_data_in_Student_table_bcec9222-b4ea-4934-8aab-3eeb820378d0.png" medium="image">
			<media:title type="html">Table_data_in_Student_table</media:title>
		</media:content>

		<media:content url="http://aspnet13.orcsweb.com/media/897102/Windows-Live-Writer_75eacc89fb20_B51C_Close_the_SQL_Compact_connection_8d2562e2-1198-425e-b170-7ff21481fdd1.png" medium="image">
			<media:title type="html">Close_the_SQL_Compact_connection</media:title>
		</media:content>
	</item>
	</channel>
</rss>
