Cách tạo crystal report thật đơn giản

Nhiều bạn có mail cho mình hỏi cách làm crystal report. hôm nay, mình làm một tut hướng dẫn các bạn cách làm với bộ thư viện mình mới viết. Hi vọng sẽ giúp ích cho các bạn.

Video Download: http://www.mediafire.com/?yug89zd2heqbd48
Library download:http://www.mediafire.com/?w63ta25yycpd6mc

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

Import và Export Excel trong .NET

Trong bài viết hôm này, mình sẽ hướng dẫn các bạn cách Import excel từ một file có sẵn vào csdl và export dữ liệu từ csdl ra 1 file excel.
Đây là thư viện đã xây dựng sẵn, các bạn cứ thế mà dùng. Chỉ cần Add Reference đến thư viện này là được.
Trong thư viện có 2 phương thức đó là:
public DataTable ImportExcel(string strFileName,string strQuery)
Có tác dụng Import file Excel theo đường dẫn strFilename với câu truy vấn sql strQuery vào 1 DataTable.
Ví dụ:
DataTable dt=ImportExcel("D:\\123.xls","Select * from Sheet1");
Tiếp theo là
public void ExportToExcel(DataSet source,string filename)
Có tác dụng là Export dữ liệu từ DataSet source ra file Excel và lưu trữ ở đường dẫn filename
Ví dụ:
ExportToExcel(ds,"C:\\123.xls");

Đơn giản vậy thôi. Chúc các bạn thành công.

Phần mềm tự động sinh code C# và Store Procedure

Đây là phần mềm tự động sinh mã thực thi chức năng của ứng dụng (tầng thứ 2 trong mô hình 3 lớp) và các thủ tục (Store procedure) cần thiết. Nó có thể giúp các bạn giảm thời gian viết code xuống rất nhiều.
Capture
Clink here to start download
Cách sử dụng
- Đăng nhập vào hệ thống như khi đăng nhập vào Sql Server
- Chọn database name
- Chọn table name
- Ấn vào các nút để sinh mã tương ứng.
- Clink phải vào vùng chữ chọn Copy All
- Paste vào ứng dụng của mình
Hi vọng tool nhỏ này sẽ giúp ích nhiều cho các bạn khi viết ứng dụng với Csharp.NET

Các bạn có thể xem hướng dẫn tạo chương trình sinh code tại đây:

Cách tạo Captcha đơn giản bằng ASP.NET

Captcha là một giải pháp hoàn hảo để chống spam khi đăng ký toàn khoản ở các trang web, các forum. Theo mình biết, có một số phần mềm tự động đăng ký tài khoản rồi post các bài viết spam ở các diễn đàn để quảng cáo hoăc với mục đích nào đó. Nhưng với captcha tự động thay đổi thì các phần mềm này sẽ phải bó tay.

Trong bài viết này, mình sẽ hướng dẫn các bạn tạo 1 captcha đơn giản cho trang web của mình thêm tính chuyên nghiệp.

Đầu tiên ở trang aspx bạn kéo vào các control như đoạn code sau:


<asp:UpdatePanel runat="server" ID="updatepanelcaptcha">
<ContentTemplate>
<asp:Image ID="captchaImage" runat="server" />
&nbsp;
<asp:ImageButton ID="ImageButton1" runat="server" ImageUrl="~/Images/Web/reload.jpg"
OnClick="ImageButton1_Click" />
</ContentTemplate>
</asp:UpdatePanel>

Khi làm xong hết và chạy thì sẽ được như hình sau: Capture


Mình cho tất cả vào update panel để khi clink vào ImageButton1 nó sẽ thay đổi captcha và trang web không bị load lại.


Bạn vào trang aspx.cs và dán vào đoạn code sau:



//Trả về đường dẫn của tập tin hình.
public string CreateCaptcha()
{
const byte LENGTH = 5;
// chiều dài chuỗi để lấy các kí tự sẽ sử dụng cho captcha
const string chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
using (Bitmap bmp = new Bitmap(120, 35))
{
using (Graphics g = Graphics.FromImage(bmp))
{
// Tạo nền cho ảnh dạng sóng
HatchBrush brush = new HatchBrush(HatchStyle.Percent80, Color.White, Color.Tan);
g.FillRegion(brush, g.Clip);
// Lưu chuỗi captcha trong quá trình tạo
StringBuilder strCaptcha = new StringBuilder();
Random rand = new Random();
float locationX = 3;
for (int i = 0; i < LENGTH; i++)
{
// Lấy kí tự ngẫu nhiên từ mảng chars
SolidBrush brushes = new SolidBrush(GetRandomColor());
string str = chars[rand.Next(chars.Length)].ToString();
strCaptcha.Append(str);
// Tạo font với tên font ngẫu nhiên chọn từ mảng fonts
Font font = new Font("Times New Roman", new Random().Next(14, 17), FontStyle.Bold);
// Lấy kích thước của kí tự
SizeF size = g.MeasureString(str, font);
// Vẽ kí tự đó ra ảnh tại vị trí tăng dần theo i, vị trí top ngẫu nhiên
g.DrawString(str, font,brushes, locationX, rand.Next(2, 10));
font.Dispose();
//định location X
locationX += size.Width + i;
}
// Lưu captcha vào session
Session["captcha"] = strCaptcha.ToString();
// Ghi ảnh trực tiếp ra luồng xuất theo định dạng gif
//Response.ContentType = "image/GIF";4
int numRandom = new Random().Next(1, 3000);
string imgFile = "captcha" + numRandom + ".jpg";
string directoryCaptcha = "~/Images/Captcha";
// Kiểm tra thư mục đã tồn tại
if (!Directory.Exists(Server.MapPath(directoryCaptcha)))
{
Directory.CreateDirectory(Server.MapPath(directoryCaptcha));
}
//lấy thông tin thư mục
DirectoryInfo direcInfo = new DirectoryInfo(Server.MapPath(directoryCaptcha));
foreach (FileInfo file in direcInfo.GetFiles(".jpg"))
{
try
{
//Xóa tất cả các tập tin hình trong thư mục hiện tại
file.Delete();
}
catch { }
}
bmp.Save(Server.MapPath(directoryCaptcha + imgFile));
return directoryCaptcha + imgFile;
}
}
}
int rrandom = 0;
int grandom = 0;
int brandom = 0;


public Color GetRandomColor()
{
Random rnd = new Random();
int ri = rnd.Next(255);
if (ri == rrandom){
ri = rnd.Next(255);
}
else{
rrandom = ri;
}
int gi = rnd.Next(255);
if (gi == grandom){
gi = rnd.Next(255);
}
else{
grandom = gi;
}
int bi = rnd.Next(255);
if (bi == brandom){
bi = rnd.Next(255);
}
else{
brandom = bi;
}
byte r = Convert.ToByte(ri);
byte g = Convert.ToByte(gi);
byte b = Convert.ToByte(bi);
return Color.FromArgb(r, g, b);
}


Trong sự kiện pageload bạn duyệt tất cả hình có trong thư mục Images và xóa nó đi rồi tạo captcha mới. Nếu không làm như vậy mỗi lần hàm CreateCaptcha được gọi là 1 hình được tạo ra. Nhiều lần như vậy sẽ tốn dung lượng lưu trữ.



if (!IsPostBack)
{
DirectoryInfo dr = new DirectoryInfo(Server.MapPath("~/Images"));
foreach (FileInfo f in dr.GetFiles())
{
f.Delete();
}
captchaImage.ImageUrl = CreateCaptcha();
}


Tương tự khi clink vào ImageButton1 để load lại captcha ta cũng làm công việc đó.



DirectoryInfo dr = new DirectoryInfo(Server.MapPath("~/Images"));
foreach (FileInfo f in dr.GetFiles())
{
f.Delete();
}
captchaImage.ImageUrl = CreateCaptcha();


Vậy là xong, bạn hãy chạy thử và xem kết quả.

Để hiểu rõ phương pháp này bạn cần biết cách sử dụng phương thức đồ họa GDI+ trong C#. Mình cũng không thể giải thích cặn kẽ từng dòng code được.
Chúc các bạn thành công!

Công cụ miễn phí cho ASP.NET

Có những công cụ bổ sung tăng cường tính năng của trang ASP.NET và giảm bớt công sức của lập trình viên. Điều tuyệt vời là nhiều công cụ rất hữu ích lại hoàn toàn miễn phí, đa phần trong số đó là mã nguồn mở.
Visual Studio .NET hay Visual Web Developer là công cụ tốt để xây dựng các trang ASP.NET, nhưng chưa phải hoàn hảo. Có những công cụ bổ sung tăng cường tính năng của trang ASP.NET và giảm bớt công sức của lập trình viên. Điều tuyệt vời là nhiều công cụ rất hữu ích lại hoàn toàn miễn phí, đa phần trong số đó là mã nguồn mở.

Xử lý văn bản với FreeTextBox

Điều khiển TextBox và TextArea cho phép người dùng nhập một đoạn văn bản, nhưng tất cả chỉ có thế, họ không thể làm gì khác: không thể đổi font chữ, kiểu chữ, màu sắc... Bạn sẽ không phải tự mình viết riêng một trình xử lý văn bản để tích hợp vào trang web của mình, vì FreeTextBox (http://www.freetextbox.com, phiên bản mới nhất 3.1.6, giấy phép: Freeware) có thể làm điều đó thay cho bạn. FreeTextBox là một công cụ xử lý văn bản khá mạnh, đặc biệt có 2 phần Design và HTML nên rất linh hoạt cho cả người dùng chuyên nghiệp và nghiệp dư. Tính năng chính của FreeTextBox bao gồm: Thay đổi font, kích thước và kiểu chữ; Chèn liên kết, Chèn ảnh; Bullet và Numbering; Sắp đoạn; Undo/Redo...



FreeTextBox còn có phiên bản Professional có phí với những tính năng mở rộng và phiên bản Distrubution bao gồm bản Pro và mã nguồn. Tuy nhiên phiên bản Free cũng đã đáp ứng được hầu hết yêu cầu thông thường.

FreeTextBox có các phiên bản dành cho ASP.NET 1.0, 1.1, 2.0, bạn phải chọn đúng phiên bản của file FreeTextBox.dll để cho vào thư mục bin. Cần chú ý là các tài nguyên như ảnh, JavaScript, xml... đã được đặt vào trong file FreeTextBox.Dll. Với ASP.NET 2.0, chúng sẽ được dùng một cách tự động, nhưng trong ASP.NET 1.1 bạn phải thêm vào web.config đoạn mã sau:

Để thêm FreeTextBox, bạn bổ sung đoạn mã này vào đầu trang:

<%@ Register TagPref*x="FTB" Namespace="FreeTextBoxControls" Assembly="FreeTextBox" %>

Và thêm đoạn mã này vào nơi bạn đặt FreeTextBox

Bạn có thể thiết lập khá nhiều thứ trong FreeTextBox: sửa đổi lại thanh Toolbar cho phù hợp với ý mình, chọn skin của toolbar (Office 2000/XP/2003/Mac) cũng như ngôn ngữ sử dụng. Bạn có thể dùng thuộc tính thiết lập hoặc dùng mã điều khiển để có được một công cụ xử lý văn bản như ý.
Ngoài ra còn có FCK Editor, RadEditor, Editor trong AJAX control tookit cũng rất hay để các bạn sử dụng.

Hộp thoại chờ với BusyBoxDotNet

Không thể tránh khỏi những lúc website của bạn phải xử lý một lượng lớn công việc hay dữ liệu, có thể mất đến vài phút. Lúc này bạn cần phải thông báo cho người dùng biết. BusyBoxDotNet là lựa chọn thích hợp cho yêu cầu này.

BusyBox (http://busybox.sourceforge.net phiên bản mới nhất là 0.3, giấy phép: mã nguồn mở), cho phép bạn hiển thị thông báo (tùy ý) đến người dùng trong khi trang web đang xử lý bên dưới. Sau khi tải về thư viện của BusyBox (BusyBoxDotNet.dll và ICSharpCode.SharpZipLib.dll), bạn đặt chúng vào thư mục bin và tiến hành các bước sau:

- Thêm đoạn mã sau vào section trong web.config

verb="*"

type="BusyBoxDotNet.ResourceHttpHandler, BusyBoxDotNet" />

- Đăng kí điều khiển mới ở đầu trang

<%@ Register Assembly="BusyBoxDotNet" Namespace="BusyBoxDotNet" TagPref*x="busyboxdotnet" %>

- Thêm tiếp đoạn mã sau


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

- Thêm một điều khiển busyboxdotnet vào bất cứ chỗ nào bạn muốn. Giống như các điều khiển Timer hay FileDialog, vị trí của điều khiển này không quan trọng.


Để sử dụng tính năng BusyBox, thêm đoạn mã sau vào sự kiện cần nhiều thời gian xử lý:

System.Threading.Thread.Sleep(3000);

Chú ý, khi BusyBox hiện lên thì không thể tương tác với tất cả các thành phần phía dưới trang web.

Điều quan trọng đối với BusyBox là có thể điều chỉnh hộp thoại thông báo theo ý mình, bạn có thể chỉnh sửa nhiều thiết lập trong phần properties của điều khiển BusyBoxDotNet ở trên.

BusyBox có 4 chế độ hiển thị:

OnPostBackOnly: Chỉ hiện hộp thoại khi trang gọi PostBack

OnLeavingPage: Chỉ hiện hộp thoại khi đồng thời là PostBack và đang chuyển sang trang web khác

OnLoad: Hộp thoại sẽ hiện kể từ khi trang bắt đầu sinh (render) và tự động ẩn khi đã sinh xong (bất kể khoảng thời gian thiết lập ở trên đã hết hay chưa). Nếu dùng chế độ này, Overlay phải được chuyển thành False, nếu không sẽ gây ra một lỗi ngoại lệ. OnLoad sẽ không có tác dụng với sự kiện Page_Load.

Custom: Hộp thoại sẽ không tự động hiện ra mà bạn sẽ tự điều khiển thời gian xuất hiện và ẩn của nó.

Còn rất nhiều công cụ hữu ích và miễn phí khác có thể bổ sung những tính năng hay cho trang ASP.NET của bạn.

Theo PCWorld

Hướng dẫn tạo đa giao diện trong ASP.NET

Trong bài viết này, mình sẽ hướng dẫn các bạn tạo 1 trang web có nhiều giao diện và có thể thay đổi bằng cách lựa chọn ở Dropdownlist. Mình chỉ ví dụ bằng một website nho nhỏ là thay đổi màu của dòng chữ HelloWorld trên trang web.

Đầu tiên, bạn tạo lớp Theme.cs với nội dung như sau:


public class Theme
{
public string Name{ get; set; }
public Theme(string name)
{
Name = name;
}
}

Mục đích của class này là lưu tên của các theme có trong website

Tiếp theo, bạn tạo class ThemeManager.cs và có một phương thức tĩnh public static List<Theme> GetThemes() với mục đích là lấy tất cả các theme có trong thư mục App_Themes

Nội dung class đó như sau:


using System.Collections.Generic;
using System.IO;
using System.Linq;

public class ThemeManager
{
public static List<Theme> GetThemes()
{
string[] dArrInfo = Directory.GetDirectories(System.Web.HttpContext.Current.Server.MapPath("App_Themes"));
return dArrInfo.Select(d => new Theme(d.Split('\\')[d.Split('\\').Length-1].ToString())).ToList();
}
}

Bước Tiếp Theo: Chúng ta tạo một Class có tên là BasePage.cs để xác định Theme mặc định chúng ta sẽ sử dụng. Mặc định là theme red. Nội dung class này như sau:


using System;

public class BasePage : System.Web.UI.Page
{

protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
if (Session["MyTheme"] == null)
{
Session.Add("MyTheme", "Red");
Page.Theme = (string)Session["MyTheme"];
}
else
{
Page.Theme = (string)Session["MyTheme"];
}
}
}

Bước tiếp nữa bạn tạo ra thư mục App_Themes và add vào đó 2 theme RedBlue. Trong RedBlue bạn lại add vào 2 StyleSheet và gõ vào đoạn CSS sau:

BlueTheme.css


div#text
{
color:Blue;
}

RedTheme.css


div#text
{
color:Red;
}

Hình ảnh ở Solution Explorer:

Capture
Sau đó, bạn kéo vào trong thẻ body ở trang default.aspx các control như đoạn mã sau. Nhớ là thẻ div chứa chuỗi HelloWorld phải có Id=”text” vì đoạn css ở trên định dạng cho thẻ div đó.


<asp:ObjectDataSource ID="ThemeDataSource"
SelectMethod="GetThemes"
TypeName="ThemeManager"
runat="server">
</asp:ObjectDataSource>
<div>
<asp:DropDownList runat="server" ID="ddlColor" DataSourceID="ThemeDataSource"
AutoPostBack="True" ondatabound="ddlColor_DataBound"
onselectedindexchanged="ddlColor_SelectedIndexChanged"
DataTextField="Name"
DataValueField="Name">
</asp:DropDownList>
</div>
<div id="text">
Hello world!
</div>

Hình ảnh giao diện:

Capture

Tiếp theo là gõ code cho sự kiện ondataboundonselectedindexchanged của DropDownList


protected void ddlColor_DataBound(object sender, EventArgs e)
{
ddlColor.SelectedValue = Page.Theme;
}
protected void ddlColor_SelectedIndexChanged(object sender, EventArgs e)
{
Session.Add("MyTheme", ddlColor.SelectedValue);
Server.Transfer(Request.FilePath);
}

Sau đó bạn cho trang default.aspx kế thừa class BaseTheme.cs


public partial class _Default :BasePage

Bạn chạy thử và xem kết quả.

Project đính kèm: Download

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

Sử dụng webservice như một datasource

Bạn muốn sử dụng web service như một datasource cho ứng dụng của mình!

Giải pháp: Tạo một web service trả về một dataset và gọi phương thức đó ở client

Cách thực hiện (step by step)

Bước 1: Tạo 1 webservice đặt tên tùy ý, ở đây mình đặt là DemoWebservice

Capture

Bước 2: Trong App_Code/Service.cs bạn gõ vào đoạn code sau


[WebMethod]
public DataSet GetDataSet(string sql) {
SqlConnection con = new SqlConnection("Data Source=nguyenvanthanh;Initial Catalog=Demo;Integrated Security=True");
SqlDataAdapter ad=new SqlDataAdapter(sql,con);
DataSet ds=new DataSet();
ad.Fill(ds, "table1");
ad.Dispose();
return ds;
}

Chạy chương trình và bạn được như hình sau:

Capture

Bạn cứ để đó và tiếp tục làm nhé.

Bước 3: Mở thêm 1 cửa sổ Visual Studio mới vào tạo một ứng dụng Windows Form Application

- Kéo vào form 1 DataGridview

Bước 4: Tham chiếu tới web service, bạn làm từng bước 1 theo các hình sau:

Kích phải vào project ở solution explorer và chọn Add Service Reference…1

Copy địa chỉ của web service ở project trước vào ô Address rồi ấn go, ta được như hình sau:

2

Ta thấy có phương thức GetDataSet ở bên ô Operations. Ấn OK.

Bước 5: Tạo đối tượng vào sử dụng

Mình làm đơn giản như sau. Tại sự kiện formload bạn gõ vào đoạn code sau:


ServiceReference1.ServiceSoapClient sv=new ServiceSoapClient();
dataGridView1.DataSource = sv.GetDataSet("Select * from sinhvien").Tables[0];

Chạy chương trình và bạn sẽ thấy kết quả được hiển thị trên datagridview là danh sách tất cả sinh viên có trong bảng sinh viên.

Để thêm, xóa, sửa, bạn cũng viết thêm các web method trong webservice để thực hiện điều này. đó chình là phương thức Executenonquery(string sql) mà mình hay làm đó. Sau đó các bạn cũng gọi tương tự là được.

Khi bạn public web service này lên IIS của máy thì mỗi khi cần dùng chỉ cần gọi đường dẫn http://localhost/DemoWebservice/Service.asmx là có thể sử dụng được cho ứng dụng của mình.

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

Cách gắn hình ảnh vào file dll và sử dụng

Khi lập trình ứng dụng, hình ảnh là một thứ không thể thiếu để làm đẹp thêm ứng dụng. Nhưng nếu bạn add thẳng vào resource của ứng dụng thì khi build ra file exe sẽ rất nặng và làm chậm ứng dụng khi khởi động. Nếu tạo 1 thư mục và chứa hình ảnh rồi tham chiếu đến thì cũng được nhưng không hay, nó có cảm giác không chuyên nghiệp và lỡ ai đó xóa mất thì ứng dụng sẽ bị khuyết hình ảnh chỗ đó. Vậy giải pháp là tạo 1 file dll chứa các hình ảnh rồi tham chiếu đến dll đó để lấy hình ảnh ra hiển thị. Làm như vậy ta sẽ có cảm giác ứng dụng sẽ chuyên nghiệp hơn (đó là cảm giác của mình) và mọi người thấy file dll cũng ko dám xóa linh tinh (theo cảm nghĩ của mình là như vậy Open-mouthed smile)

Thôi không nói dài dòng nữa, tóm lại là đây chỉ là một cách để sử dụng hình ảnh trong ứng dụng, các bạn có thể không làm theo cũng chả sao vì nó có vài cách, ứng dụng nhỏ thì cứ add thẳng vào resource cho nó đơn giản. Bắt đầu nhé.

Bước 1: Tạo 1 project Windows Form Application đặt tên tùy ý

1

Bước 2: Add thêm 1 class library vào ứng dụng để tạo 1 file dll chứa hình ảnh

Bước 3: Add 1 resource file vào class library trên.

2

Bước 4: Add 1 vài hình ảnh vào resource file đó

3

Bước 5: Mở class1.cs ra và gõ vào đoạn code như hình sau

4

Bước 6: Build Class Library này => ta được 1 file dll.

Bước 7: Add file dll vào ứng dụng Windows Form Application

5

Bước 8: Sử dụng

6

Kết quả sau khi chạy chương trình

7

Vậy là xong rồi đó. Chúc các bạn thành công!

Cách cấu hình kết nối SqlServer khi mang ứng dụng sang máy khác

Hôm nay, mình sẽ hướng dẫn các bạn cách tạo kết nối Sql Server cho ứng dụng của mình khi mang sang máy khác sử dụng mà mất thông số kết nối.

- Đầu tiên, bạn tạo 1 file text chứa thông tin kết nối, file text đó có nội dung như sau:

Server:
Database:
UserName:
Password:

Các giá trị ban đầu để trống. Mình đặt tên file là ConnectString.con

- Tiếp theo, bạn tạo 1 class tên là Helper.cs với nội dung như sau:


using System.Data.SqlClient;
using System.IO;

namespace iloveit1208_ConnectSQLServer
{
class Helper
{
public string Server{ get; set; }
public string Database { get; set; }
public string UserName { get; set; }
public string Password { get; set; }

public Helper()
{
StreamReader reader=new StreamReader("ConnectString.con");
this.Server = reader.ReadLine().Split(':')[1];
this.Database = reader.ReadLine().Split(':')[1];
this.UserName = reader.ReadLine().Split(':')[1];
this.Password = reader.ReadLine().Split(':')[1];
reader.Close();
}
public SqlConnection GetConnect()
{
if (this.UserName!="")
return new SqlConnection("Data Source=" + this.Server + ";Initial Catalog=" + this.Database + ";User Id=" + this.UserName + ";Password=" + this.Password + ";");
else
return new SqlConnection("Data Source=" + this.Server + ";Initial Catalog=" + this.Database + ";Integrated Security=True");
}
public static void WriteFile(string server,string data,string uid,string pass)
{
StreamWriter writer = new StreamWriter("ConnectString.con");
writer.WriteLine("Server:"+server);
writer.WriteLine("Database:"+data);
writer.WriteLine("UserName:" + uid);
writer.WriteLine("PassWord:" + pass);
writer.Close();
}
}
}

Chức năng của class này là cung cấp các phương thức đọc và ghi vào file ConnectString.con

- Tiếp theo bạn tạo 1 form kết nối như hình sau:

1

Form này sẽ tự động hiện lên cho bạn cấu hình kết nối SqlServer khi mất kết nối (trường hợp chuyển sang máy khác).

Code cho từng nút bạn có thể xem ở Project đính kèm.

- Tạo 1 form chính cho chương trình, mình làm đơn giản chỉ có một nút kiểm tra kết nối.

2

Trong sự kiện formload, bạn phải kiểm tra xem kết nối tới máy chủ có thành công hay không, nếu thất bại thì formconnection sẽ được hiện lên để cấu hình lại kết nối.


private void Form1_Load(object sender, EventArgs e)
{
try
{
Helper h = new Helper();
SqlConnection con = h.GetConnect();
con.Open();
con.Close();
}
catch (Exception)
{
frmConnection f=new frmConnection();
f.ShowDialog();
}
}

Nguyên lý chỉ đơn giản vậy thôi, mình sẽ đính kèm project ở dưới nếu bạn không hiểu đoạn code này thì reply lại mình sẽ giải thích kĩ càng.

Link download Project: Download

Chúc các bạn thành công.

Cách lưu hình ảnh vào csdl Sql Server

Đầu tiên, các bạn tạo csdl có 1 table như hình dưới:


Tiếp theo, các bạn tạo 1 form có giao diện như hình dưới (Ở giữa là 1 picture box và bên cạnh là các nút điều khiển.



Tiếp theo, các bạn tạo 1 class có tên AccessData.cs. Nội dung class đó như sau:

using System;
using System.Data;
using System.IO;
using System.Linq;
using System.Data.SqlClient;

namespace ImageInSQL
{
class AccessData
{
public SqlConnection conn;

public string connectionString =
"Data Source=.\\SQLEXPRESS;AttachDbFilename='E:\\My Code\\C#\\ImageInSQL\\ImageInSQL\\ImageData.mdf';Integrated Security=True;User Instance=True";
public AccessData()
{
conn = new SqlConnection(connectionString);
}
public void StorePicture(string filename)
{
byte[] imageData = null;
// Read the file into a byte array
using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
{
imageData = new Byte[fs.Length];
fs.Read(imageData, 0, (int) fs.Length);
}
string shortFileName = filename.Split('\\').Last();
using (SqlConnection conn = new SqlConnection(connectionString))
{
SqlCommand cmd = new SqlCommand("InsertImage", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@filename", shortFileName);
cmd.Parameters["@filename"].Direction = ParameterDirection.Input;
cmd.Parameters.Add("@Image",SqlDbType.Image);
cmd.Parameters["@Image"].Direction = ParameterDirection.Input;
// Store the byte array within the image field
cmd.Parameters["@Image"].Value = imageData;
conn.Open();
cmd.ExecuteNonQuery();
}
}

public byte[] RetrieveImage(int id)
{
byte[] imageData = null;
conn.Open();
SqlCommand cmd = new SqlCommand("select Image from tbl_Image where ID="+id+"",conn);
// Assume previously established command and connection
// The command SELECTs the IMAGE column from the table

using (SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess))
{
reader.Read();
// Get size of image data – pass null as the byte array parameter
long bytesize = reader.GetBytes(0, 0, null, 0, 0);
// Allocate byte array to hold image data
imageData = new byte[bytesize];
long bytesread = 0;
int curpos = 0;
int chunkSize = 1;
while (bytesread < bytesize)
{
// chunkSize is an arbitrary application defined value
bytesread += reader.GetBytes(0, curpos, imageData, curpos, chunkSize);
curpos += chunkSize;
}
}
conn.Close();
// byte array ‘imageData’ now contains BLOB from database
return imageData;
}
public int NumberImageInDB()
{
conn.Open();
SqlCommand cmd=new SqlCommand("select Max(ID) from tbl_Image",conn);
int kq = int.Parse(cmd.ExecuteScalar().ToString());
cmd.Dispose();
conn.Close();
return kq;
}
public string FileNameOfImage(int id)
{
conn.Open();
SqlCommand cmd = new SqlCommand("select FileName from tbl_Image where ID="+id+"", conn);
string kq = cmd.ExecuteScalar().ToString();
cmd.Dispose();
conn.Close();
return kq;
}
}
}

Các bạn cần chỉnh lại connectionString cho đúng với máy mình.
vào phần code của form khai báo đối tượng AccessData và 2 biến private để lưu tên file và chỉ số ảnh

AccessData ac=new AccessData();
private string filename;
private int i=1;

Tiếp theo sẽ là code cho từng nút:
Nút select picture

OpenFileDialog dlg = new OpenFileDialog();
dlg.Filter ="All File (*.*)|*.*|JPG Files(*.JPG)|*.JPG | GIF Files(*.GIF)|*.GIF";
if (dlg.ShowDialog(this) == DialogResult.OK)
{
pictureBox1.Image = Image.FromFile(dlg.FileName);
filename = dlg.FileName;
blFileName.Text = filename.Split('\\').Last();
}

Nút save to DB

try
{
ac.StorePicture(filename);
MessageBox.Show("Successful!", "Infomation", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (SqlException ex)
{
MessageBox.Show(ex.Message.ToString(), "Infomation", MessageBoxButtons.OK, MessageBoxIcon.Error);
}

Nút picture first

byte[] img = ac.RetrieveImage(1);
MemoryStream str = new MemoryStream(img);
pictureBox1.Image = Image.FromStream(str);
i = 1;
button5.Enabled = false;
button3.Enabled = true;
blFileName.Text = ac.FileNameOfImage(1);

Nút next

button5.Enabled = true;
if (i < ac.NumberImageInDB()) i++;
else button3.Enabled = false;
byte[] img = ac.RetrieveImage(i);
MemoryStream str = new MemoryStream(img);
pictureBox1.Image = Image.FromStream(str);
blFileName.Text = ac.FileNameOfImage(i);

Nút preview

button3.Enabled = true;
if (i >1) i--;
else button5.Enabled = false;
byte[] img = ac.RetrieveImage(i);
MemoryStream str = new MemoryStream(img);
pictureBox1.Image = Image.FromStream(str);
blFileName.Text = ac.FileNameOfImage(i);

Nút picture last

byte[] img = ac.RetrieveImage(ac.NumberImageInDB());
MemoryStream str = new MemoryStream(img);
pictureBox1.Image = Image.FromStream(str);
i = ac.NumberImageInDB();
button3.Enabled = false;
button5.Enabled = true;
blFileName.Text = ac.FileNameOfImage(ac.NumberImageInDB());

Vậy là xong, các bạn có thể test thử và xem kết quả.
Download code full

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

5. Sử dụng SqlDataAdapter, DataSet, DataTable

Ở bài trước bạn đã biết cách xử lý và hiện kết quả ra màn hình dùng Data Reader. Chú ý rằng : nếu chỉ muốn xem thông tin thì dùng Data Reader. Bài này hướng dẫn sử dụng DataSet để xử lý kết quả kết hợp với DataAdapter. Không giống với DataReader, tạo ra các đối tượng dùng interface System.DataIDataReader, thì DataSet là một thành phần đặc trưng của ADO.NET được sử dụng bởi tất cả các nhà cung cấp dữ liệu (data provider). Dataset có thể hoàn toàn độc lập và sử dụng khi kết nối hoặc ngắt kết nối khỏi nguồn. Mục đích cơ bản của DataSet là cung cấp xử lý xem xét dữ liệu lưu trữ trong một ‘memory cache’. Nếu như một DataSet không kết nối tới cơ sở dữ liệu thì làm sao mà xử lý dữ liệu và save lại vào database ? Đây là lí do mà DataAdapter ra đời. Hãy nghĩ DataAdapter chính là một chiếc cầu nối giữa DataSet và Data Source. Nếu không có một DataAdapter nào thì DataSet không thể truy cập bất cứ DataSource nào. DataAdapter đảm bào việc kết nối và truyền thông tin cho DataSet.

Tìm hiểu về ObjectModel

Đầu tiên thì mình đưa ra một số so sánh giữa DataSet và DataReader nhé, để các bạn tránh hay hỏi nhiều về việc : Lúc nào thì xài DataSet và lúc nào thì xài DataReader, giống và khác nhau như thế nào ?

So sánh DataSet và DataReader

Nếu bạn đơn giản chi muốn lấy dữ liệu và trình bày nó ra thôi thì dùng DataReader. Đặc biệt trường hợp mà bạn đọc với một số lượng lớn dữ liệu, ví như là vòng lặp tới hàng triệu dòng kết quả dữ liệu, bạn muốn tốc độ đọc nhanh và trình bày nhanh thì DataReader được sử dụng cho mục đích này, NHANH và TIỆN LỢI, cho việc ĐỌC dữ liệu.

Nếu bạn muốn chỉnh sử dữ liệu rồi update thông tin dữ liệu lại database thì bạn sử dụng DataSet. DataAdapter lấp đầy (fill) dữ liệu vào DataSet bằng cách sử dụng một DataReader, thêm vào đó resource cần được lưu trữ vào để sử dụng khi ngắt kết nối. Vì vậy việc sử dụng DataSet tốn nhiều tài nguyên hơn DataReader rất nhiều, bạn cần cân nhắc ở đây lúc nào sử dụng thành phần nào thì tốt, tránh lạm dụng quá. Nếu như bạn muốn đọc dữ liệu và viết ra dưới dạng XML, hoặc export database schema, viết lại db dưới dạng XML,…. thì nên sử dụng DataReader.

Giới thiệu sơ qua về DataSet

DataSet trong ADO.NET là một bước phát triển lớn trong việc phát triển ứng dụng cơ sở dữ liệu đa hệ. Khi lấy và chỉnh sửa dữ liệu, duy trì liên tục kết nối tới Data Source trong khi chờ user yêu cầu thì rõ ràng là tốn tài nguyên máy rất nhiều.

DataSet giúp ích ở đây rất lớn. Vì DataSet cho phép lưu trữ dữ liệu và chỉnh sửa tại ‘local cache’, hay gọi là offline mode. Có thể xem xét và xử lý thông tin trong khi ngắt kết nối. Sau khi chỉnh sửa và xem xong thì tạo một kết nối và update dữ liệu từ local vào Data Source.

Dữ liệu trong DataSet được lưu trữ dưới dạng một Collection các Tables và bạn cần phải xử lý thông qua các lớp DataTable -> DataRow và DataColumn.

Bảng dưới đây là kiến trúc DataSet.

Bạn chỉ cần tưởng tượng rằng : bạn có một cái bể nước (DataSource) , một cái máy bơm (DataAdapter) và một cái thùng đựng nước (DataSet). Thì khi lấy nước dùng cái bơm lấy nước từ bể, kiểm tra và lọc nước sau đó lại dùng cái bơm hút lại về cái bể nước. Đó chính là vai trò của cái bơm và DataAdapter tương tự như vậy.

Tương quan 3 lớp như thế này :

Có 4 cách tạo DataAdapter :


// Cách 1 : Đơn giản chỉ khai báo tạo đối tượng Adapter
SqlDataAdapter da = new SqlDataAdapter();
// Cách 2 : Thiết lập đối tượng SqlCommand
SqlDataAdapter da = new SqlDataAdapter(cmd);
// Cách 3 : Thiết lập query và đối tượng SqlConnection
SqlDataAdapter da = new SqlDataAdapter(sql, conn);
// Cách 4 : Thiết lập query và mệnh lệnh thực thi
SqlDataAdapter da = new SqlDataAdapter(sql, connString);

Giới thiệu về DataTable và thành phần kèm

Nằm trong lớp : System.Data.DataTable. Có cấu trúc theo cấu trúc của bảng trong cơ sở dữ liệu gồm các hàng và cột nên có 2 thành phần kèm theo là : DataRow và DataColumn

DataRow sẽ là tập hợp các cột (record-set)

DataColumn là tập hợp các hàng cùng một đặc tính. (Field)


DataTable dt = new DataTable();
DataColumn col = dt.Columns[“Contact”]; // Cột Contact
DataColumn col = dt.Columns[2];
DataRow row = dt.Rows[2];

Làm việc với DataSet và DataAdapter

Tạo một dataset :


DataSet ds = new DataSet();
DataSet ds = new DataSet(“DataSet Name”);

Nếu bạn dùng cách 1 thì theo mặc định DataSet sẽ có tên là “NewDataSet”, cách thứ 2 là bạn đặt tên luôn cho DataSet bên trong constructor. Hoặc bạn có thẻ thay đổi tên của DataSet bằng thuộc tính ‘DataSetName’

Có nhiều cách xử lý với DataSet như:

· + Sử dụng thông qua Adapter

· + Đọc từ một tài liệu XML

Thử xử lý dữ liệu bằng một ví dụ :


using System;
using System.Data;
using System.Data.SqlClient;

namespace MSSQL_Server
{
class Database
{
static void Main(string[] args)
{
// Tạo connection strin
string connString = @"Server = NguyenVanThanh
Integrated Security = True;
Database = Demo
// Tạo SQL query
string sql = @"SELECT MaSV,TenSV FROM SinhVien";
// Tạo connection
SqlConnection conn = new SqlConnection(connString);
try
{
// Mỏ kết nối
conn.Open();
// Tạo Adapter
SqlDataAdapter da = new SqlDataAdapter(sql, conn);
// Tạo DataSet
DataSet ds = new DataSet();
// Lấp đầy kết quả vào DataSet
da.Fill(ds, "sinhvien");
// Tạo DataTable thu kết quả từ bảng
DataTable dt = ds.Tables["sinhvien"];
// In kết quả ra Console
foreach (DataRow row in dt.Rows)
{
foreach (DataColumn col in dt.Columns)
Console.WriteLine(row[col]);
Console.WriteLine("".PadLeft(20, '='));
}
}
catch (Exception e)
{
// Bắt lỗi
Console.WriteLine(e.Message);
}
finally
{
// Đóng kết nối
conn.Close();
}
}
}
}


Phân tích bài đơn giản ở trên nha.

Sau khi đã mở kết nối thì ta tạo một Adapter. Adapter này chứa thông tin về SQL query cần thực thi và một đối tượng kết nối conn, sau đó tạo một DataSet. Lúc này thì DataSet chưa có gì. Sau đó lấp đầy kết quả vào DataSet bằng method ‘Fill’ của Adapter. Từ đó hiểu thêm rằng : Adapter tự động thực thi câu lệnh SQL , thu lấy kết quả và gán hết vào DataSet. Khác với DataReader cần có một đối tượng SqlComnmand đễ xử lý. Nếu khi lấp đầy kết quả vào DataSet mà không gán tên bảng nào thì tự động trong DataSet tên lần lượt từng bảng là ‘TableN’ với bảng đầu tiên là Table, Table1,Table2…TableN.

Nếu một query được thực thi lại nhiều lần thì DataSet sẽ cập nhật thông tin từng đó bảng vào trong .

Chú ý trong Adapter ở trên nếu thay bằng cách tạo Adapter dưới đây :


SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = new SqlCommand(sql, conn);

Thì kết quả thu được giống hệt nhau, không có gì thay đổi.

DataSet có thể chứa nhiều table vì thế khi xử lý Table nào cần phải gán vào DataTable một tên table cụ thể. Và cuối cùng dùng DataColumn và DataRow để xử lý DataTable đó. Đó là cách extract dữ liệu từ DataSet.

Các bạn có thể xem video sau để hiểu rõ hơn: download