MỚI NHẤT

Thứ Năm, 2 tháng 6, 2016

[EXE + APK] Phần mềm ĐẾM GIỜ

Code ngày code đêm, code quên cả ăn và hậu quả là... bụng 1 múi.
Lướt facebook vô tình đọc được tit "Chỉ cần tập các động tác này trong 20s bạn sẽ có cơ bụng 6 múi", ô thật bất ngờ, không thể tin nổi.
Bình thường cũng muốn tập tành lắm đấy nhưng do yêu cái máy tính quá nên nhiều lúc không dứt ra được, đọc được cái tit này nghĩ ngay đến "ờ thì chẳng nhẽ lại không bỏ ra 20s được"  :))
Click vào xem hóa ra đó là các động tác tập bụng, mỗi động tác thực hiện trong 20s, thực hiện hết động tác này đến tư thế kia, và quan trọng mỗi cái chỉ cần 20 giây



=> Trong đầu lóe ra ý tưởng: tại sao không dùng phần mềm đếm ngược để thông báo cho ta sau mỗi 20s ấy? Những phần mềm hiện tại chỉ cho phép đếm 1 lần rồi dừng, thế là lại có ý tưởng ngay để code :))
Phần mềm Đếm giờ đã ra đời  :D

Chức năng của phần mềm chỉ là: đếm ngược thời gian 1 số lần nhất định, sau khi hết mỗi 1 khoảng thì có thông báo bằng âm thanh.

Mình viết trên C# đã khá lâu rồi. Trong phần mềm có sử dụng:
- Dùng timer để đếm giờ
- Phát nhạc, file âm thanh
- User Control để vẽ hình vành khăn thể hiện tiến trình
- Giao diện tùy chỉnh...

dem-gio-window
Giao diện khi đếm giờ
dem-gio-window
Giao diện khởi động

Tự dưng có hứng học lập trình android, vọc vạch trong gần 1 tuần, Đếm giờ trên android đã hoàn chỉnh, chức năng cũng tương tự như trên window.
Giao diện ứng dụng:

dem-gio-android

Trong ứng dụng có các tính năng:

  • EditText, Button cơ bản (drawable, ripple...)
  • Activity single top: Activity chỉ khởi tạo 1 lần
  • Navigation bar: Navigation View và chuyển qua lại giữa các thẻ
  • Itent: Mở ứng dụng khác, mở ứng dụng từ thanh thông báo
  • Fragment, hiệu ứng chuyển cảnh (animation)
  • Notification: Hiển thị thông tin trên thanh thông báo, bắt sự kiện khi click thông báo (new Intent)
  • Press Back: Xử lý sự kiện ấn Back
  • Press twice to exit: ấn back 2 lần để thoát
  • Progressbar: hình dạng tùy chỉnh
  • Shared preferences... Lưu cấu hình chương trình: Sáng màn hình, show notification
  • Phát âm thanh
  • Luôn sáng màn hình: KeepScreenOn


==>> DOWNLOAD phần mềm:

Bạn nào cần mã nguồn, comment ở dưới để mình gửi cho.

Thứ Ba, 24 tháng 6, 2014

[WindowForm] Sử dụng Timer và một số chức năng với Timer

"Timer" là một điều khiển khá hữu ích trong C# - Winform. Timer tương tự như "setInterval" hay "setTimeOut" trong JavaScript đều có chức năng thực hiện một số chức năng nhất định trong các khoảng thời gian lặp lại. Một đoạn chương trình sẽ được lặp đi lặp lại với khoảng nhất định mà không ảnh hưởng đến các tiến trình khác.
Có nhiều loại Timer: System.Windows.Forms.Timer, System.Timers.Timer, System.Threading.Timer. Nhưng để đơn giản bây giờ chúng ta sẽ sử dụng điều khiển Timer của Windows.Forms.
Sử dụng Timer và một số chức năng với Timer

Để khai báo 1 đối tượng Timer cách đơn giản là vào Toolbox tìm "Timer" rồi kéo vào form
Sử dụng Timer và một số chức năng với Timer

Đặt các thuộc tính cho Timer
Sử dụng Timer và một số chức năng với Timer

Trong đó Interval là khoảng thời gian sẽ lặp lại, đơn vị tính miliseconds. Ở ví dụ ta đã bật cho Timer chạy và đặt khoảng thời gian cho nó là 1 giây (1000 miliseconds).

Sự kiện duy nhất của Timer là Timer_Tick cho phép ta thay đổi sự kiện mỗi khi timer lặp lại thời gian. Tức là khi timer lặp lại thì code trong hàm Timer_Tick sẽ được thực hiện.

Bây giờ, tôi sẽ hướng dẫn một vài công dụng với Timer:

- Đồng hồ chạy số trong Window Form

Ta có 2 label để hiển thị thời gian và ngày tháng, 2 label sẽ được thay đổi nội dung sau từng giây. Vậy chúng ta cần 1 điều khiển timer với khoảng lặp là 1000, nội dung Timer_Tick tương tự như sau:
private void timer1_Tick(object sender, EventArgs e)
{
    lblTime.Text = (DateTime.Now.Hour < 10 ? "0" + DateTime.Now.Hour.ToString() : DateTime.Now.Hour.ToString()) + ":" + (DateTime.Now.Minute < 10 ? "0" + DateTime.Now.Minute.ToString() : DateTime.Now.Minute.ToString()) + ":" + (DateTime.Now.Second < 10 ? "0" + DateTime.Now.Second.ToString() : DateTime.Now.Second.ToString());
    lblDate.Text = DateTime.Now.DayOfWeek.ToString() + ", " + (DateTime.Now.Day < 10 ? "0" + DateTime.Now.Day.ToString() : DateTime.Now.Day.ToString()) + "/" + (DateTime.Now.Month < 10 ? "0" + DateTime.Now.Month.ToString() : DateTime.Now.Month.ToString()) + "/" + DateTime.Now.Year;
}

- Ảnh động trong Window Form

Ta đã biết ảnh động thực sự là tập hợp các ảnh tĩnh được hiển thị lần lượt, lặp đi lặp lại sau 1 khoảng thời gian nhất định. Và ở đây ta dùng Timer để đặt cái khoảng thời gian nhất định đó. Mỗi khi đến điểm Tick thì thay đổi ảnh ở trong PictureBox.
/// <summary>
/// Biến kiểm tra ảnh động
/// Không hiểu sao phải dùng thêm 1 biến ngoài để kiểm tra
/// </summary>
private int _img = 1;
private void timer1_Tick(object sender, EventArgs e)
{
    if (_img == 1)
    {
        // Thay đổi ảnh
        pictureBox1.Image = NhacViec.Properties.Resources.Alarm2;
        _img = 2;
    }
    else
    {
        pictureBox1.Image = NhacViec.Properties.Resources.Alarm1;
        _img = 1;
    }
}


Demo về 2 ví dụ này có tại phần mềm Nhắc việc.
Nếu có hứng thú các bạn có thể xem thêm các phần Timer khác và sự khác nhau giữa chúng tại đây.

Thứ Bảy, 21 tháng 6, 2014

[WindowForm] Sử dụng NotifyIcon - Cách ẩn chương trình xuống khay hệ thống

Nhiều chương trình như UniKey, KasperSky, SkyDrive, DropBox... đều có 1 phần chương trình chạy ngầm trong hệ thống và có 1 biểu tượng icon nhỏ ở khay hệ thống - system tray. Bạn có 1 chương trình yêu cầu phải chạy liên tục và chạy ẩn (không hiện ở taskbar), có 1 biểu tượng ở khay hệ thống để người dùng có thể tương tác với chương trình. Rất đơn giản chúng ta sẽ sử dụng NotifyIcon cho việc này.
Sử dụng NotifyIcon - Cách ẩn chương trình xuống khay hệ thống

1. Sử dụng NotifyIcon

- Các bạn search ở ToolBox "NotifyIcon" và kéo vào trong form của mình.

- Các thuộc tính của NotifyIcon:
Sử dụng NotifyIcon - Cách ẩn chương trình xuống khay hệ thống

BaloonTipIcon, BaloonTipText, BaloonTipTitle hiện ra như 1 thông báo nhỏ ở khay hệ thống (nếu chúng ta cho hiện).
Sử dụng NotifyIcon - Cách ẩn chương trình xuống khay hệ thống

ContextMenuStrip là lựa chọn menu khi ấn chuột phải vào notifyIcon.
Text là phần hiện lên khi ta di chuột vào notifyIcon.
Đặt mặc định cho notifyIcon có Visible hay không!?

- Thiết lập các menu chuột phải cho NotifyIcon
Trong ToolBox ta tìm vào kéo 1 đối tượng ContextMenuStrip.
Thêm các MenuItem cho contextmenu đấy. Ở đây hỗ trợ nhiều loại như MenuItem (giống 1 button), ComboBox, TextBox, Separator (vạch ngăn cách).
Sử dụng NotifyIcon - Cách ẩn chương trình xuống khay hệ thống

Thêm sự kiện click cho các MenuItem này.

Để sử dụng ContextMenuStrip này cho NotifyIcon đừng quên thiết lập ở phần NotifyIcon như trên.

2. Ẩn chương trình xuống khay hệ thống

Việc này thực sự chỉ là ẩn chương trình đang chạy và cho hiện 1 cái NotifyIcon lên. NotifyIcon có các MenuItem để tương tác với chương trình đang chạy, như mở chương trình, thoát chương trình..., các chức năng do ta đặt ở phần ContextMenuStrip phía trên. Vì ẩn chương trình và chương trình luôn chạy ngầm nên ta phải tính làm sao để giảm thiểu tài nguyên sử dụng, form chúng ta cho chạy ngầm phải ít tốn tài nguyên, chỉ để thực hiện các chức năng cơ bản (như để gọi các form to hơn) hoặc chỉ là 1 service.

Để thực hiện ẩn chương trình ta thêm 1 button, hoặc gán vào các sự kiện khác (minimize form chẳng hạn)
Sự kiện click của button này như sau
private void btnExit_Click(object sender, EventArgs e)
{
 // Cho hiện notifyIcon
    notifyIcon1.Visible = true;
 // Hiện BaloonTip hoặc không
    notifyIcon1.ShowBalloonTip(10);
 
 // Chọn ẩn
    this.Hide();
 // Hoặc
    this.ShowInTaskbar = false;
 WindowState = FormWindowState.Minimized;
 // Hoặc cả 2 để ẩn form
}

Phần việc còn lại là do NotifyIcon phụ trách. Chẳng hạn ta muốn click chuột phải để hiện menu context, click chuột trái để mở form: Ta thêm 1 sự kiện Click hoặc MouseClick cho NotifyIcon
private void notifyIcon1_MouseClick(object sender, MouseEventArgs e)
{
    if(e.Button == System.Windows.Forms.MouseButtons.Left)
 {
  // Ẩn notifyIcon đi
  notifyIcon1.Visible = false;
  // Cách này
  WindowState = FormWindowState.Normal;
  this.ShowInTaskbar = true;
  // Hoặc
  this.Show();
  // Hoặc cả 2 miễn là phải tương ứng với lúc ẩn
 }
}

Thứ Sáu, 20 tháng 6, 2014

[WindowForm] Customize Form - Tùy chỉnh form, tạo form có hình dạng bất kỳ

Bạn thấy nhiều phần mềm có những form có hình dạng rất lạ (không phải hình chữ nhật, có border thông thường). Bạn hoàn toàn có thể tạo những form mang hình dạng đặc biệt tùy ý một cách đơn giản.
Customize Form - Tùy chỉnh form, tạo form có hình dạng bất kỳ
Như Photoshop chẳng hạn

Sau đây tôi sẽ hướng dẫn các bạn cách tạo 1 form tùy ý và các thao tác liên quan.

1. Tạo form với hình dạng tùy ý

Thực chất việc này là đặt 1 hình ảnh làm nền cho form rồi cho những phần còn lại "biến mất".
Customize Form - Tùy chỉnh form, tạo form có hình dạng bất kỳ

- Đầu tiên bạn thiết kế 1 cái hình ảnh làm nền cho form. Những phần không cần thiết thì bạn nên để trong suốt, rồi xuất ra ảnh .PNG

- Tiếp theo đặt "BackColor" của form là White, "BackgroundImage" là hình ảnh vừa tạo, FormBorderStyle None

- Đây là phần quan trọng nhất: Cuộn xuống chọn "TransparencyKey" là White => Nó sẽ tìm tất cả phần nào của background form màu trắng để làm trong suốt phần đó. 
Cách này vô cùng đơn giản, để có thể tạo được 1 form tùy ý. Chính vì thế mà nó có nhiều chỗ không trong suốt cho lắm, đặc biệt là những đường giao nhau giữa 2 màu, đoạn đường chéo... Những điểm này khá nhỏ vẫn có thể chấp nhận được. Nếu bạn muốn có nó một cách hoàn hảo + opacity của từng phần trong form thì phải dùng đến phần xử lý đồ họa.

2. Di chuyển cho form tùy chỉnh

Với 1 form đã tạo được như trên vấn đề là khi ta loại bỏ border của form thì làm sao để di chuyển form đây??? Chỉ còn cách code!!!  :)
Việc code còn đem lại cho ta những tùy chọn về di chuyển form do ta tự quyết định: chẳng hạn có cho form "chui ra phía ngoài màn hình" không hoặc là bị bó hẹp trong khuôn khổ của màn hình, cho phép người dùng click chuột ở đâu để di chuyển form???

Trong phần global ta khai báo các biến toàn cục như sau:
/// <summary>
/// Di chuyển form
/// </summary>
private bool drag = false;
private Point dragCursor, dragForm;

Quay lại phần thiết kế để double click và thêm 3 sự kiện: MouseDown, MouseMove, MouseUp cho form.
Chỉnh sửa các sự kiện đấy như sau:
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
    drag = true;
    dragCursor = Cursor.Position;
    dragForm = this.Location;
}

private void Form1_MouseMove(object sender, MouseEventArgs e)
{
    int wid = SystemInformation.VirtualScreen.Width;
    int hei = SystemInformation.VirtualScreen.Height;
    if (drag)
    {
        // Phải using System.Drawing;
        Point change = Point.Subtract(Cursor.Position, new Size(dragCursor));
        Point newpos = Point.Add(dragForm, new Size(change));
        // QUyết định có cho form chui ra ngoài màn hình không
        if (newpos.X < 0) newpos.X = 0;
        if (newpos.Y < 0) newpos.Y = 0;
        if (newpos.X + this.Width > wid) newpos.X = wid - this.Width;
        if (newpos.Y + this.Height > hei) newpos.Y = hei - this.Height;
        this.Location = newpos;
    }
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
    drag = false;
}

Như vậy hiện tại bạn có thể click vào bất cứ phần nào không trong suốt của form để di chuyển form.

3. Thêm một số phần khác

Khi loại bỏ border thì đồng nghĩa với việc không còn các nút Minimize, Maximize, Exit và box-shadow của form. Vậy ta phải thêm thủ công như sau

Thêm các nút điều khiển

Tự thiết kế hình ảnh cho các nút hoặc đơn giản chỉ là các button thông thường. Sau đó thêm sự kiện click như sau
private void btnMini_Click(object sender, EventArgs e)
{
    this.WindowState = FormWindowState.Minimized;
}

private void btnExit_Click(object sender, EventArgs e)
{
    Application.Exit();
} 

Thêm box shadow cho form 

Chúng ta phải override 1 thủ tục của form như sau:
/// <summary>
///  Drop Shadow cho form
/// </summary>
protected override CreateParams CreateParams
{
    get
    {
        CreateParams cp = base.CreateParams;
        // Bóng đổ
        cp.ClassStyle |= 0x20000;
        // Load các control cùng lúc
        cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED
        return cp;
    }
}

Phần load các control 1 lúc có thể áp dụng cho các form khác, form có nhiều control. Chẳng hạn form bạn có rất nhiều control và thường xuyên phải Visible/Invisible chúng lần lượt. Như vậy khi các control hiện lên sẽ bị trễ nhìn rất mất mỹ quan. Khi thêm phần này vào thì các control sẽ hiển thị ra cùng 1 lúc, không có hiện tượng trễ.

Thứ Tư, 18 tháng 6, 2014

[WindowForm] Các cách lưu thông tin cài đặt cho ứng dụng C# - Apps setting

Đôi khi chúng ta cần lưu trữ thông tin nào đó liên quan đến người dùng, do người dùng cài đặt. Những thông tin này phải được lưu trữ một cách lâu dài, xuyên suốt từ phiên làm việc này đến phiên làm việc khác. Tức là ta phải có cách để lưu thông tin cài đặt của người dùng

Có nhiều cách để lưu thông tin cài đặt chương trình, sau đây là một số cách phổ biến, dễ sử dụng

1. Lưu thông tin cài đặt vào Registry

Registry là bộ nhớ lưu trữ các thông tin cài đặt của hệ điều hành cũng như của các phần mềm trên nó. Do vậy ta có hoàn toàn có thể lưu trữ và lấy các thông tin trên Registry.

Ưu điểm của cách này là truy xuất nhanh, ít bị thay đổi bởi người không hiểu biết, người dùng và chỉ có lập trình viên mới có thể biết được cấu trúc, vị trí lưu trên Registry.

Nhược điểm là khi muốn lưu, đọc dữ liệu trên Registry đều phải thực thi nhiều code và yêu cầu lập trình viên phải nắm vững cấu trúc của Registry. Các thông tin cài đặt này chỉ có tác dụng với máy đã tạo ra, khi copy ứng dụng sang máy khác thì thông tin cài đặt bị mất.

2. Lưu trực tiếp trên phần mềm

Nền tảng .NET FrameWork cho phép người dùng phần mềm chỉnh sửa và lưu các thông tin cài đặt ngay trên ứng dụng. Cách lưu thông tin cài đặt này rất dễ sử dụng, lập trình. Khi thêm 1 đối tượng setting thì .NET tự động sinh ra 1 class để quản lý các thông tin setting đó.

Để bắt đầu với cách này bạn click đúp vào "Properties" trong tab "Solution Explorer". Sau đó trong tab "Settings" hãy thêm những trường cài đặt mong muốn. Ở đây .NET hỗ trợ nhiều kiểu dữ liệu: bool, string, int, datetime...
Các cách lưu thông tin cài đặt cho ứng dụng C# - Apps setting

Sau khi đã lưu các thông số này, chúng ta đọc, lưu thông tin vào như sau:
// Đọc thông tin
string MySetting = ShowGridView.Properties.Settings.Default.MySetting;

// Ghi thông tin
ShowGridView.Properties.Settings.Default.CheckBox = true;
// Lưu lại
ShowGridView.Properties.Settings.Default.Save();

3. Lưu trên file bên ngoài

Một cách lưu trữ thông tin cài đặt nữa là lưu chúng ra một file text thông thường hoặc một file được mã hóa. Với cách này cũng có nhiều kiểu lưu trữ, tùy vào cách xử lý của lập trình viên:
  • Lưu vào 1 file text thông thường đặt cùng thư mục của ứng dụng. Các thông tin sẽ được lưu trữ theo tiêu chuẩn của lập trình viên. Sau đó lập trình viên phải đọc nội dung của file và xử lý chuỗi để lấy được các thông tin đã ghi trước đó.
  • Lưu vào 1 file XML với quy cách nhất định. Với cách này khi dùng các thủ tục đọc, ghi xml thì công việc đọc, lưu thông tin cài đặt sẽ dễ dàng hơn.
  • Lưu file vào thư mục AppData của từng User. Khi đó với các User khác nhau cùng sử dụng máy tính sẽ có những thông tin cài đặt khác nhau.
  • Lưu thông tin ra file .INI. Cách này bạn có thể tham khảo tại đây.
Vì các thông tin được lưu trên một file riêng biệt nên người dùng có thể dễ dàng thay đổi, hoán chuyển các thông tin cài đặt khi cần thiết (chỉ cần việc cut/paste file ra 1 chỗ khác).

Thứ Tư, 23 tháng 4, 2014

[SQLExpress] Lấy bản ghi ngẫu nhiên với SQL và LinQ

Trong nhiều trường hợp ta phải chọn ngẫu nhiên 1 hoặc một số bản ghi trong CSDL như: chọn 5 bài đăng ngẫu nhiên trong blog, chọn 1 câu hỏi ngẫu nhiên cho chương trình trả lời câu hỏi...
Trong cú pháp của SQL, LinQ đều có cách để làm việc này

I. SQL query lấy bản ghi ngẫu nhiên

Lấy bản ghi ngẫu nhiên với SQL và LinQ

Cấu trúc
SELECT TOP 5 [IDpost]
  FROM [dbo].[tbPost]

  ORDER BY NEWID()  -- Trình tự sắp xếp ngẫu nhiên

Trong đó NEWID() quy định 1 trình tự sắp xếp mà các bản ghi được sắp xếp ngẫu nhiên, đây chính là cơ sở để lấy các bản ghi ngẫu nhiên.

II. Lấy bản ghi ngẫu nhiên bằng code LINQ

Dùng phương thức SKIP() của IEnumerable để nhảy qua n bản ghi, với n là một số ngẫu nhiên. Thực chất cách này không phải là lấy ngẫu nhiên một số bản ghi mà nếu có thì cũng chỉ hiệu quả với bài toán lấy ngẫu nhiên 1 bản ghi duy nhất.
Lấy bản ghi ngẫu nhiên với SQL và LinQ

Cấu trúc của cách làm này như sau:
var p = from post in db.tbPosts
  select new { post.IDpost, post.title };  // Chọn dữ liệu từ LinQ

int count = p.Count();
var random = new System.Random();                   // Khởi tạo biến random
var postRD = p.Skip(random.Next(count)).Take(5);    // Tiến hành random và chọn 5 record đầu tiên
dataSet1BindingSource.DataSource = postRD;          // Điền dữ liệu vào datagridview

Theo code này thì bạn sẽ lấy được 5 bản ghi liền nhau ở vị trí ngẫu nhiên > sẽ có lúc nhận được không đủ 5 bản ghi. Không đúng với bài toán lắm.
Vậy giải pháp ở đây là chạy câu lệnh SQL chửa NEWID() bằng LINQ
var postRD = db.ExecuteQuery<tbPost>("SELECT * FROM tbPost ORDER BY NEWID()").Take(5);
dataSet1BindingSource.DataSource = postRD;          // Thiết lập dữ liệu cho binddingridview


Chủ Nhật, 20 tháng 4, 2014

[LINQ] LinQ là gì và tại sao nên dùng LinQ?

Với SQLExpress để truy vấn dữ liệu ta phải dùng đến các câu lệnh - Query khá phức tạp. Hơn nữa để sử dụng trong ứng dụng C# lại thêm 1 tầng phức tạp nữa với các câu lệnh: dùng ConnectionString khởi tạo kết nối tới DataBase, tự khai báo các biến để chạy 1 lệnh - command, rồi còn phải tính toán đầu ra của câu lệnh... Thật là quá phức tạp nếu như ta có 1 chương trình "khủng".
Vậy làm sao để giải quyết vấn đề này? 
Một đề xuất là sử dụng Linq to SQL.
Không chỉ áp dụng cho truy vấn SQL mà LinQ còn có khả năng hỗ trợ trên nhiều nền tảng khác: XML, SQLite, Excel...

I. LinQ là gì?

LinQ là gì và tại sao nên dùng LinQ

Để giảm gánh nặng thao tác trên nhiều ngôn ngữ khác nhau và cải thiện năng suất lập trình, Microsoft đã phát triển giải pháp tích hợp dữ liệu cho .NET Framework có tên gọi là LINQ (Language Integrated Query), đây là thư viện mở rộng cho các ngôn ngữ lập trình C# và Visual Basic.NET (có thể mở rộng cho các ngôn ngữ khác) cung cấp khả năng truy vấn trực tiếp dữ liệu Object, CSDL và XML.
LINQ là một tập hợp các thành phần mở rộng cho phép viết các câu truy vấn dữ liệu ngay trong một ngôn ngữ lập trình, như C# hoặc VB.NET. Khi tạo một đối tượng LINQ thì Visual Studio sẽ tự động sinh ra các lớp có các thành phần tương ứng với CSDL của chúng ta. Khi muốn truy vấn, làm việc với CSDL ta chỉ việc gọi và truy xuất các hàm, thủ tục tương ứng của LINQ mà không cần quan tâm đến các câu lệnh SQL thông thường.
Tóm lại LINQ ra đời để giảm công sức cho những quá trình đơn giản và “chung chung” trước đây.

Điểm mạnh (chưa chắc về độ mạnh, nhưng hay) của LINQ là “viết truy vấn cho rất nhiều các đối tượng dữ liệu”. Từ CSDL, XML Data Object … thậm chí là viết truy vấn cho một biến mảng đã tạo ra trước đó. Vì vậy mới có các khái niệm LinQ to SQL, LinQ to XML, blo bla ….
Tuy nhiên so với mô hình Entity (Entity Framework), LINQ có yếu điểm là chậm và thiếu nhất quán (hiện đại tất phải hại điện).

LINQ có từ bản .NET 3.5, vậy nên tối thiểu chương trình của bạn phải chạy trên nền tảng này.
Visual Studio 2008, hoặc các phiên bản Express của nó là các bộ công cụ phát triển tiêu biểu cho ứng dụng dùng LINQ.

II. Sử dụng LinQ

LinQ là gì và tại sao nên dùng LinQ
Câu lệnh SELECT trong SQL được thực hiện bởi LINQ
Trong phần này tôi sẽ sử dụng 1 project demo để các bạn thấy được cách làm việc với LINQ như thế nào?!
CSDL là 1 bảng tbTest với 2 trường: id (kiểu int, tự động tăng - Identity) và Feild1 (kiểu nvarchar(50)).

1. Khởi tạo đối tượng LinQ to SQL

Trong project chọn Add > Data > LinQ to SQL classes

LinQ là gì và tại sao nên dùng LinQ?

Ở đây tôi tạo 1 file DB.dbml trong thư mục DB để dễ quản lý.
Sau khi có được file ta tiến hành kéo các table cần thiết vào để tự động sinh các thủ tục LinQ
LinQ là gì và tại sao nên dùng LinQ?

Vậy là xong, ta đã tạo được các thủ tục cần thiết để làm việc với LINQ. Easy??!!   :)

2. Truy vấn dữ liệu

Tương tự như Entity ta phải khai báo 1 biến DataContext để tương tác với LinQ
DB.DBDataContext db = new DB.DBDataContext();  

Có 2 kiểu truy vấn dữ liệu:
Query Syntax
var abc = from p in db.tbTests
          where p.id > 10
          select p;

// Hoặc chọn một số trường
var abc = from p in db.tbTests
          where p.id > 10
          select new
          {
              p.id,
              p.Feild1
          };
Method Syntax
var xyz = db.tbTests.Where(p => p.id > 10).Select(p => new { p.id, p.Feild1 });

Câu truy vấn SQL tương ứng
SELECT [id]
      ,[Feild1]
  FROM [dbo].[tbTest]
  WHERE [id] > 10

Chọn từ nhiều bảng theo kiểu Inner Join (lấy những bản ghi có điều kiện thỏa mãn)
// Query Syntax
var result = from p in products
             join c in categories on p.CategoryID equals c. CategoryID
             select new
             {
                 ProductName=p.ProductName,
                 CategoryName=c.CategoryName
             };

// Hoặc chọn từ 2 bảng bằng cách from 2 lần  :)
var result = from p in products
             from c in categories
             where p.ProductName equals c.CategoryName
             select new
             {
                 ProductName=p.ProductName,
                 CategoryName=c.CategoryName
             };

// Method Syntax
var result = products.Join(
             categories,
             p=>p.CategoryID,
             c=>c.CategoryID,
             (p,c) => new
             {
                 ProductName=p.ProductName,
                 CategoryName=c.CategoryName
             });

Cú pháp khác tương tự các câu lệnh trong SQL.
Các biến ở trên trả về có kiểu IEnumrable, 1 loại kiểu dữ liệu giống như List. Các thao tác cơ bản với loại biến này:

  • xyz.FirstOrDefault(): Chọn bản ghi đầu tiên hoặc mặc định
  • xyz.Skip(5): Nhảy qua n bản ghi
  • xyz.Take(5): Lấy n bản ghi đầu tiên
  • xyz.ToList(): Chuyển sang kiểu List
  • xyz.Count(): đếm số bản ghi
  • xyz.Select(...), xyz.Where(...), xyz.Join(...): Các câu lệnh truy vấn theo kiểu Method Syntax
  • bla bla

Đôi khi bạn không tìm được cú pháp thích hợp hoặc LinQ không hỗ trợ loại truy vấn mà vốn có trong SQL thì bạn có thể thực hiện trực tiếp câu lệnh đó thông qua LinQ:
var result = db.ExecuteQuery<int>("SELECT NEXT VALUE FOR seq_tbCanBo")

3. Thêm, sửa, xóa dữ liệu thông qua LinQ

Thêm dữ liệu
DB.tbTest a = new DB.tbTest();      // Khai báo đối tượng mới
a.Feild1 = txtFeild1.Text;      // id là giá trị tự động tăng > ko cần thay đổi
db.tbTests.InsertOnSubmit(a);   // Thêm đối tượng a vào
db.SubmitChanges();     // Lưu thay đổi

Sửa dữ liệu
var a = (from p in db.tbTests
         where p.id == int.Parse(txtId.Text)
         select p).FirstOrDefault();
a.Feild1 = txtFeild1.Text;
db.SubmitChanges();

Xóa dữ liệu

var a = (from p in db.tbTests
         where p.id == int.Parse(txtId.Text)
         select p).FirstOrDefault();
db.tbTests.DeleteOnSubmit(a);
db.SubmitChanges();

III. Bindding

Bindding là cách thuận tiện để thay đổi, cập nhật, thêm mới bản ghi ở CSDL một cách dễ dàng trực quan, sử dụng LinQ.
Giả sử ta thực hiện Bindding ở 1 bảng, có 2 chế độ (kiểu hiển thị) là GridView Detail:
  • Chế độ GridView: có 1 gridview để hiển thị các bản ghi trong bảng, tương tự như khi chúng ta chạy câu truy vấn SELECT * trong SQL
  • Detail: các Control cho phép thay đổi giá trị của bản ghi đang được chọn ở Gridview. Khi click vào 1 hàng ở Gridview thì dữ liệu của hàng đó sẽ được điền tự động vào các Control này.

Cách dùng Bindding:
Trong chế độ Design form, mở cửa sổ Data Sources, ở đây các bảng trong file DB.dbml (được tạo khi khởi tạo LinQ) sẽ được hiển thị, giúp ta có thể kéo vào trong form của mình
Với mỗi bảng có các tùy chọn để chọn chế độ xem: Gridview, Detail,...
LinQ là gì và tại sao nên dùng LinQ?
Tạo Bindding bằng cách kéo thả
Sau khi kéo như vậy thì nó sinh ra 1 đối tượng là tbTestBinddingSource, đây chính là đối tượng tương tác với SQL, LinQ.
Quy định nguồn dữ liệu cho Bindding:
// DataSource là 1 bảng có sẵn
tbTestBindingSource.DataSource = db.tbTests;

// Datasource là một đối tượng IEnumrable lấy từ truy vấn LINQ
tbTestBindingSource.DataSource = result;

Bạn có thể kéo 1 BinddingNavigator để thực hiện các thao tác thêm, xóa dễ dàng
LinQ là gì và tại sao nên dùng LinQ?

Khi đã có Bindding như thế này rồi thì việc thêm sửa xóa cực kỳ đơn giản, không cần code nhiều, sau khi thay đổi trên gridview, detail để lưu tất cả các thay đổi chỉ cần
tbTestBindingSource.EndEdit();
db.SubmitChanges();

Các thao tác có thể làm với BinddingSource
tbTestBindingSource.RemoveCurrent();    // Xóa hàng hiện tại

// Di chuyển trên gridview
tbTestBindingSource.MoveFirst();
tbTestBindingSource.MoveLast();
tbTestBindingSource.MoveNext();
tbTestBindingSource.MovePrevious();

tbTestBindingSource.Position = 5;   // Xác định vị trí cho Bindding

Sau số thao tác thay đổi trên grid view, bạn muốn xem số hàng thêm mới, sửa xóa??
int insert = db.GetChangeSet().Inserts.Count;
int update = db.GetChangeSet().Updates.Count;
int delete = db.GetChangeSet().Deletes.Count;


Tham khảo project demo trên tại đây.
Các bạn có thể truy cập liên kết để có thêm thông tin, các thao tác với LINQ.

Thứ Bảy, 19 tháng 4, 2014

[Windows Form] DevExpress - thư viện lập trình cho windows form với một số thủ thuật

DevExpress là 1 hệ thống thư viện lập trình cực hữu ích cho việc thiết kế, lập trình form 1 cách đơn giản, chuyên nghiệp.
DevExpress bao gồm rất nhiều Control (gần như có thể thay thế hoàn toàn các Control của .NET) và còn nhiều Control ghép, mở rộng mà .NET không có. Nó chứa từ các điều khiển cơ bản như TextEdit, Button, MessageBox, PictureBox, GridView... đến các điều khiển mở rộng, nâng cao như SearchLookupEdit, RibbonBar, SpreadSheet Control... Các điều khiển tích hợp nhiều chức năng, tùy chỉnh giúp người lập trình bớt phải code.

Điểm đặc biệt ở Dev là nó hỗ trợ nhiều Skin khác nhau, theo ý tôi thì chúng đều rất đẹp và nhìn có vẻ rất chuyên nghiệp, lập trình viên có thể để người dùng chọn Skin ngay trong khi chạy chương trình.
Vì nhiều tính năng như vậy nên bộ thư viện cũng khá là nặng và tốn thời gian khi chạy chương trình trong lần đầu load form.

Trang chủ: https://www.devexpress.com/
Download (cracked): Bản 13.1.4 (hiện nay đã có bản 13.2)

Sau đây tôi xin giới thiệu một số thủ thuật, cách sử dụng Dev hiệu quả hơn

I. Tạo form PreLoad cho form chính

Với 1 chương trình tương đối lớn, nhiều control cần load khi khởi tạo, chạy lần đầu thì việc phải đợi lâu, độ delay lớn sẽ gây cảm giác không tốt tới người dùng. Điều chúng ta có thể làm là thử tạo 1 form pre load cho main form. Tức là trong khi đang load form chính (tốn thời gian) thì ta cho hiển thị 1 form splash nhẹ hơn lên trước, sau khi form chính load xong thì form splash này mất đi. Trong form splash này có thể cho hiển thị tên phần mềm, copyright, progress bar... để người dùng không có cảm giác phải đợi lâu.

Để tạo được 1 from pre load ta làm theo các bước sau:
- Trong Project tạo 1 form DevExpress splashForm, ta sửa form này theo ý muốn ( như hình trên chẳng hạn)
- Trong form chính kéo 1 control "splashScreenManager" vào và đặt thuộc tính "ActiveSplashFormTypeInfo" cho nó là tên form splash vừa tạo ở trên. Có thể tùy chỉnh thêm 1 số tùy chọn.

II. Áp dụng, thay đổi skin cho form

Thay đổi giao diện áp dụng với form Ribbon. Có nhiều skin như Office 2013, Win 7, Mac...
Để thay đổi được cả giao diện ribbon và giao diện form phải cài đặt thuộc tính "RibbonStyle" của thành phẩn Ribbon Control là "Office2013".

Trong 1 RibbonPage > RibbonPageGroup nào đó bạn tạo 1 "RibbonGalleryBarItem", đặt tên cho nó (là rbiGallery chẳn hạn)

Trong phần code ta làm như sau:
using DevExpress.Skins;
using DevExpress.LookAndFeel;
using DevExpress.XtraBars.Ribbon;
using DevExpress.XtraBars.Ribbon.Gallery;

//
//
namespace ABC
{
    public partial class XYZ : DevExpress.XtraBars.Ribbon.RibbonForm
    {
        public XYZ()
        {
            InitializeComponent();
            // Gallery Skin
            DevExpress.XtraBars.Helpers.SkinHelper.InitSkinGallery(rbiGallery, true);
            UserLookAndFeel.Default.SetSkinStyle("Default");

Thêm nhiều skin hơn bằng cách sửa file "Program.cs", thêm đoạn sau vào:
DevExpress.UserSkins.BonusSkins.Register();
DevExpress.Skins.SkinManager.EnableFormSkins();

III. Sử dụng MessageBox của DevExpress

Việc sửa giao diện cho form đã ổn, vấn đề là những MessageBox của .NET vẫn chưa được thay đổi và không đồng bộ với giao diện của form. Vậy làm sao để khắc phục?
Dev cũng hỗ trợ cả cái MessageBox này với tên "XtraMessageBox", việc sử dụng XtraMessageBox cũng giống hệt khi ta sử dụng MessageBox. Thuận tiện hơn nữa là MessageBox này cũng thay đổi giao diện khi ta thay đổi giao diện của form.

Sử dụng XtraMessageBox như sau:
using DevExpress.XtraEditors;   // MessageBox
//
//
XtraMessageBox.Show("Có lưu file không?", "File chưa được lưu", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);

Như vậy là phần lớn các Control của form đã có thể thay đổi, tùy chỉnh với Dev.

Thứ Năm, 10 tháng 4, 2014

Giới thiệu ASP MVC - Hướng dẫn cơ bản để tạo một website ASP MVC đầu tiên (P2)

Trong bài Giới thiệu ASP MVC - Hướng dẫn cơ bản để tạo một website ASP MVC đầu tiên (P1) tôi đã giới thiệu với các bạn sơ qua về ASP.NET MVC và cách tạo một trang web MVC đơn giản. Trong phần 2 này tôi sẽ giúp bạn code 1 vài trang cho web site và 1 vài tiện ích liên quan tới MVC.

I. Tổ chức code MVC

Đầu tiên là trang chủ - trang hiển thị thông tin các sản phẩm. Vì yêu cầu trả về thông tin sản phẩm + loại sản phẩm, tức là lấy thông tin từ 2 bảng khác nhau vì thế ta khai báo thêm 1 class có các trường: ID, TenSP, TenLSP như sau:
public class Product
    {
        public int ID { get; set; }
        public string TenSP { get; set; }
        public string TenLoaiSP { get; set; }
    }
Trong DefaultController, để làm việc với DB Entity ta khai báo 1 biến toàn cục để sử dụng trong tất cả các Action:
SanPhamDB db = new SanPhamDB(); // SanPhamDB là tên Database, db là biến Entity
Controller thực hiện các câu lệnh và trả về kết quả cho browser thông qua View. Để có thể làm được điều đó ta phải khai báo 1 hàm có kiểu trả về là ActionResult (các hàm kiểu này có nhiều loại kiểu trả về, đọc tài liệu đính kèm để biết thêm chi tiết). Cụ thể với phần Index của dự án này (hiển thị thông tin sản phẩm, loại sản phẩm) có phần code như sau:
#region Trang chủ
        public ActionResult Index()
        {
            // Entity
            // LINQ
            // //Query syntax:
            var product = (from p in db.tbSanPhams select p).ToList(); // Biến danh sách chọn từ Database tbSanPham

            List<Product> prod = new List<Product>(); // Khai báo ‘prod’ là kiểu List các Product (Product là class khai báo ở trên)
            
            for (int i = 0; i < product.Count(); i++)
            {
                Product p = new Product();
                p.ID = product[i].Id;
                p.TenSP = product[i].TenSanPham;

                int type = product[i].LoaiSanPham; // Lấy ID loại sản phẩm của sản phẩm ‘i’ 

                // LInQ 
                // Method systax
                var p2 = (db.tbLoaiSanPhams.Where(p1 => type == p1.LoaiSanPham).Select(p1 => p1.TenLoaiSanPham)).ToList();
// Chọn tên loại sản phẩm từ bảng ‘tbLoaiSanPham’ với điều kiện ‘LoaiSanPham’ ở 2 bảng bằng nhau.

                p.TenLoaiSP = p2[0];
                prod.Add(p); // Thêm ‘p’ vào List ‘prod’
            }
            return View(prod);
        }
#endregion
Giao diện trang Index (hiển thị danh sách các sản phẩm)

Lưu ý:
  • Kiểu List() là kiểu danh sách tương tự như Array nhưng nó linh hoạt hơn Array: không cần phải khai báo số phần tử của mảng, có các hàm, thủ tục: Add, Sort
  • Có hai loại sử dụng cú pháp Entity (LINQ):
    Query syntax: Cú pháp la lá giống SQL
    Method systax: Cú pháp theo kiểu các class được khai báo sẵn: db.tb.Where(…).Select… Điểm chú ý là các biến của kiểu khai báo này không có sẵn, do đó ta phải khai báo chúng trực tiếp trong câu lệnh. Ví dụ: db.tbLoaiSanPhams.Where(p1 => type == p1.LoaiSanPham).Select(p1 => p1.TenLoaiSanPham). Trong đó khai báo biến là p1.
  • Còn #region #endregion chỉ đơn giản là tạo ra 1 khu vực với nhiệm vụ nhất định, trong này ta có thể khai báo nhiều hàm, thủ tục khác nhau. Sau này ta có thể thu gọn các khu vực này để code trông đơn giản, dễ nhìn hơn
Để trả về thông tin cho HTML ta phải sử dụng View().
View là phần hiển thị thông tin được sử lý dựa vào thông tin trả về từ Controller. View cũng tương tự như các trang HTML thông thường. View cũng có thể dùng các trang Master (như ASP Webform) hoặc Layout (ở Razor)
View phải có tên giống với tên hàm tương ứng ở Controller. Như trên ta phải tạo 1 view có tên là Index.aspx hoặc Index.cshtml
Để tạo view nhanh ta trỏ con trỏ đến tên hàm, ấn Ctrl M >> Ctrl V.

Lưu ý hàm trên trả về 1 giá trị là ’View(prod);

II. Cách trả dữ liệu về View để hiển thị ra trình duyệt

 1.  Trả về dưới dạng Dynamic Data tức là bằng ViewBag.<name> hoặc ViewData[“<name>”]; trong đó <name> là tên tùy ý do lập trình viên đặt (ta nên đặt chúng theo đúng quy cách, hạn chế các trường hợp đặc biệt…). Hai dạng này có chức năng, cách dùng tương tự nhau. Ở Controller gán giá trị cho chúng như 1 biến thông thường mà không cần phải khai báo
ViewBag.Sloaisp = “Hello”;
ViewData[“Sloaisp”] = “Hello”;
Ở View ta lấy các giá trị này như sau:
ASP: <%= ViewBag.Sloaisp %>   <%= ViewData[“Sloaisp”] %> 
Razor: @ViewBag.Sloaisp;  @ViewData[“Sloaisp”]

2.  Trả về dữ liệu có cấu trúc: 
Như hàm trên trả về 1 List giá trị có kiểu Product. View sẽ nhận List này rồi xử lý, trả về HTML tương ứng Cụ thể trong phần khai báo của aspx ta khai báo như sau:
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/View.Master" Inherits="System.Web.Mvc.ViewPage<DEMOmvc.Models.Product>" %>
Trong phần thân ta lấy thông tin “prod” như sau:
<% foreach(var item in Model)
{ %><%= item.ID %>

<%= item.TenSP %>  

<%= item.TenLoaiSP %>  

<%= Html.ActionLink("Sửa", "Edit", new { ID = item.ID }) %> | <%= Html.ActionLink("Xóa", "Delete", new { ID = item.ID })%>

<% } %>

Với các trang Edit, Delete, New ta cũng thực hiện tương tự.




III. LinQ và làm việc với LinQ

          LinQ là một cách giao tiếp với CSDL. Nó giúp ta làm việc với CSDL một cách ra dễ dàng thông qua những hàm, thủ tục được khai báo sẵn. LinQ giúp ta dễ dàng trong việc sử dụng Bindding sau này.

Trong nội dung bài viết này tôi sẽ sử dụng LinQ và biến SanPhamDB db được khai báo ở trên.

- Thêm một bản ghi vào bảng:
tbSanPham SP = new tbSanPham(); // Khai báo class “SP” có kiểu tbSanpham  (tương ứng với tên bảng do Entity tự động tạo ra)

string TenSP = Fcollect["TenSP"]; // Lấy thông tin từ Form HTML chuyển vào, khi có hàm ActionResult phải nhận 1 tham số tương ứng: “FormCollection Fcollect”

int LoaiSP = int.Parse(Fcollect["LoaiSP"]);
SP.TenSanPham = TenSP; // Thêm thông tin vào biến SP
SP.LoaiSanPham = LoaiSP;
db.tbSanPhams.Add(SP); // Thếm biến SP vào List tbSanPhams
db.SaveChanges(); // Lưu lại

- Sửa bản ghi có Id = ID:
tbSanPham SP = db.tbSanPhams.First(m => m.Id == ID); // Lấy bản ghi đầu tiên có Id bằng ID truyền vào từ HTML (viết theo kiểu Method Syntax)

SP.TenSanPham = TenSP; // Sửa các thông tin lấy từ HTML
SP.LoaiSanPham = LoaiSP;
UpdateModel(SP);
db.SaveChanges();

- Xóa 1 bản ghi có Id = ID
tbSanPham SP = db.tbSanPhams.First(m => m.Id == ID);
db.tbSanPhams.Remove(SP);
db.SaveChanges();

Trên đây là các thao tác cơ bản để làm việc với LinQ, bạn có thể tham khảo.


IV. Rewrite URL trong MVC

        Các Controller, View đã được tạo vậy nó sẽ được map đến địa chỉ URL như thế nào???
Các thông tin về URL được quy định trong RouteConfig.cs trong thư mục App_Start. Trong hàm RegisterRoutes ta khai báo như sau:
routes.MapRoute(
                name: "Default1",
                url: "{action}/{ID}",
                defaults: new { controller = "Default", action = "Index", ID = 0 }
);
routes.MapRoute(
                name: "Default",
                url: "{action}.html",
                defaults: new { controller = "Default", action = "Index" }
);

Mỗi cái đăng ký Route có các tham số: Tên, địa chỉ URL, action và các tham số mặc định…
Bằng cách này bạn có thể tạo ra những địa chỉ "thân thiện" cho website của mình.

Chúc bạn thành công!

Thứ Tư, 9 tháng 4, 2014

Giới thiệu ASP MVC - Hướng dẫn cơ bản để tạo một website ASP MVC đầu tiên (P1)

I. Giới thiệu về ASP MVC

       Công nghệ MVC là một công nghệ mới ra cách đây 1 vài năm gì đấy… Nó không chỉ có trong ASP mà còn ở các ngôn ngữ lập trình khác: PHP, JSP… Công nghệ MVC mang lại cho coder một cách tổ chức code khoa học hơn, giúp soạn thảo mã nguồn nhanh hơn, dễ chỉnh sửa, chương trình chạy nhanh, hiệu quả hơn.


      MVC tức là Model, View, Control là 3 thành phần cơ bản của công nghệ. Cách thức tổ chức code được chia thành 3 bộ phận rõ rệt, mỗi bộ phận có 1 chức năng riêng. Cụ thể là:
  1.  Model chứa các file mã nguồn liên quan đến nhập, xuất dữ liệu, giao tiếp giữa cơ sở dữ liệu và chương trình. Các file trong Model có thể là các class mặc định của Visual tạo ra: ADO.NET Entity Database hoặc LINQ to SQL. Ngoài ra, lập trình viên cũng có thể thêm vào những class chứa thông tin phục vụ cho chức năng của chương trình
  2.      View chứa các file hiển thị chương trình, nó tiếp nhận thông tin từ Controller rồi trả về Browser mã HTML, JavaScript… Các file trong View có thể dựa trên cơ sở ASP (file *.aspx) hoặc dựa trên CSharp HTML (file *.cshtml). Về cơ bản 2 loại file này giống nhau về cách thức làm việc chúng chỉ khác nhau đôi chút về phần code. Với file ASPX thì cấu trúc hoàn toàn tương tự như trong Web Form cũng được xây dựng từ các file *.aspx và *.Master; có điều trong trường hợp này file *.aspx không lấy dữ liệu từ file *.aspx.cs tương ứng mà nó nhận giá trị trả về từ Controller. Còn loại cshtml thì cũng tương tự, được xây dựng từ các file *.cshtml và *.layout, cũng có chức năng như ASPX.
  3.       Control là thư mục chứa các file điều khiển Controller, nó nhận thông tin từ Form HTML, Model, Session, Cookie…, xử lý theo yêu cầu và trả về cho View để View hiển thị ra trình duyệt
ASP MVC còn tích hợp sẵn cách Rewrite URL (Router Manager) nhằm tạo ra các URL thân thiện.

II. Tạo website ASP MVC đầu tiên

        Giới thiệu là thế, bây giờ chúng ta sẽ băt tay vào thực hiện 1 dự án MVC cụ thể để thấy được cách thức hoạt động của các thành phần trong chương trình. Các bạn chỉ cần hiểu được chức năng, cách hoạt động của các thành phần trong chương trình này là có thể vận dụng chúng trong mọi dự án MVC khác. Dự án: Tạo 1 website để quản lý các sản phẩm Đầu vào: Database gồm 2 bảng
+ tbSanPham: chứa thông tin sản phẩm, gồm các trường Id (int identity), TenSanPham, LoaiSanPham (int) (chẳng hạn sản phẩm “Genius” có loại sản phẩm là “Chuột”, một loại sản phẩm có thể có nhiều sản phẩm)

+ tbLoaiSanPham: chứa thông tin loại sản phẩm, gồm các trường LoaiSanPham (int identity), TenLoaiSanPham



Yêu cầu:

-       Có các trang:

 + Hiển thị thông tin các sản phẩm cùng tên loại sản phẩm tương ứng

 + Thêm mới sản phẩm, loại sản phẩm

 + Chỉnh sửa sản phẩm


 + Xóa sản phẩm


Bây giờ chúng ta cùng bắt đầu vào công việc

     Mở Visual Studio, chọn New Project >> ASP.NET MVC 4 (với Visual 2013 là có MVC 5) 




-          Sửa sổ Solution Explore gồm các thư mục mặc định:
   
  Trong thư mục Controllers tạo 1 Controller với tên tùy ý + "Controller" (bắt buộc):

 t
         Trong thư mục Model tạo Model để giao tiếp với CSDL:

Có thể chọn kiểu ADO.NET Entity hoặc LINQ to SQL

Sau đó khai báo Connection String (đến SQL Express hoặc Server Local của Visual…)

Chọn các bảng cần thiết để add vào Model

Khi tạo xong thì trong Model có các file miêu tả các class, các method để làm việc với SQL. Chẳng hạn nó tự động sinh ra một namespace là: <Tên dự án>.Models
Trong đó có các class, các hàm thực thi:
<Database name> <Table> <Field>. Ví dụ: SanPhamDB > tbSanPham > TenSanPham, SanPhamDB db = new SanPhamDB();
<Database name> <Method> hoặc <Database name> <Table> <Method>. Ví dụ: db.tbSanPhams.Add(SP); db.SaveChanges(); Update(SP); db.tbSanPhams.Remove(SP);


Vậy là chúng ta đã tạo được 1 website MVC, trong phần tiếp theo tôi sẽ hướng dẫn các bạn code xử lý các sự kiện, và nhiều hơn nữa trong ASP.NET MVC.