又一種 ASP.NET 連接 MySQL 方法

  1. 安裝 MySQL
  2. 安裝 MySQL Connector/ODBC
    安裝完成的檢查:控制台\系統管理工具\資料來源 (ODBC)\驅動程式
    看看有沒有成功安裝 (捲軸往下拉,應該會有 Mysql ODBC 5.1 Driver)
  3. 建立資料庫、資料表、灌資料
  4. 開啟 VWD,建立 ASP.NET Web 應用程式
  5. 在方案總管的專案(not方案)上方按右鍵,選擇『加入參考』,切換到『瀏覽』標籤,搜尋位置『C:\Program Files (x86)\MySQL\MySQL Connector Net x.x.x\Assemblies\』,看要進入哪個版本,找到『Mysql.Data.dll』加入
  6. xxx.aspx.vb 加入 Imports MySql.Data.MySqlClient 
    xxx.aspx.cs 加入 using MySql.Data.MySqlClient;
  7. 撰寫程式碼
    成功執行連線與檢索畫面:


VB 參考程式碼 (.NET 不支援 set 和 let 了)

Dim oConn As MySqlConnection
Dim sConnStr As String
Dim oDbAdapter As MySqlDataAdapter
Dim oTable As Data.DataTable

資料庫連線字串‘Database=資料庫
sConnStr = String.Format(“Server=localhost;Port=3307;User=rrrrr; Password=pppp; Database=test; Pooling=false")  

開啟資料庫連線
oConn = New MySqlConnection(sConnStr)
oConn.Open()

執行 SQL 語法取得資料集
oTable = New Data.DataTable()
oDbAdapter = New MySqlDataAdapter(“SELECT * FROM first", oConn)
oDbAdapter.Fill(oTable)

將資料集餵給 GridView 當作 DataSource (後記得要 Binding)
GridView1.DataSource = oTable
GridView1.DataBind()

C# 參考程式碼:

//建立連接字串與物件
string cnnString = “Server=localhost;Port=3307;Database=test;User=rrrrr;Pwd=pppp";
MySqlConnection cnx = new MySqlConnection(cnnString);
MySqlDataAdapter adapter = new MySqlDataAdapter();
//執行 SQL 語法
string cmdText = “SELECT * FROM first";
MySqlCommand cmd = new MySqlCommand(cmdText, cnx);
//取得資料集
DataSet ds = new DataSet();
adapter.SelectCommand = cmd;
adapter.Fill(ds);
//餵給GridView
GridView1.DataSource = ds;
GridView1.DataBind();

遇到的問題:
  1. 安裝了 Appsev 的 MySQL,會沒有 Connector NET 6.7.4 這個模組,導致在『加入參考』的時候會找不到 Mysql.Data.dll 這個函式庫,因此還是要安裝官方的 MySQL
  2. Appserv 的 MySQL 有提供一個 Web-based 的管理介面,官方的管理介面則是Workbench這個軟體,官方的MySQL叫做 WinMySQLAppserv MySQL就叫做MySQL
  3. 當有 Appserv MySQL時,因為MySQL預設的Port3306,所以 WinMySQL Port會被改成3307

[C#] 批次更改檔案的副檔名

昨天因為我的 HTC One V 又失靈了,造成我記憶卡中許多的相片檔案遺失,後來我找到了 LOST.DIR 這個資料夾,裡面存放了許多只有流水編號,沒有副檔名的檔案,我測試了一個檔案,將它的副檔名加上手機相機一般預設的檔案格式 .jpg,果然成功的救回了不少相片,但是要一個一個自己手動去把每個檔案都加上副檔名還原真的很費工,所以就寫了一個批次更改副檔名的程式。

雖然光寫程式的時間就足以完成手動更改的工作,不過就像某些演算法的概念,第一次辛苦一點花多一點時間做一件事,接下來後面的類似工作就可以省去這件事情而且可以很快速的透過這個流程來完成。

Rename_Batch (x86)

使用方法:
(1)將這個程式放到你將要批次修改的目錄中,並點擊執行
(2)上方輸入框 – 輸入在目前的目錄中,你想要修改的檔案的副檔名,例如你想修改所有副檔名是 .txt 的檔案,則輸入 .txt,當然你可以都不要輸入,這樣子就會修改像上面那些沒有副檔名的檔案了
(3)下方輸入框 – 輸入要修改成的副檔名,例如你想將某個檔案修改成 .jpg 的檔案,則輸入 .jpg
(4)按下按鈕,若跳出 “修改完成!" 的訊息,即完成修改
/*
 * Program: Batch Of Renaming File Extension
 * Language: C# .NET Framework 3.5
 * Author: Veck Hsiao @ Taiwan, National Chung Cheng University
 * Time: June/29/2012
 * Usage: Change all assigned file extensions in current directory in batch
 */
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace Rename_Batch
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{

DirectoryInfo di = new DirectoryInfo(".");
string NewExt = textBox1.Text.Trim();
string SourceExt = textBox2.Text.Trim();

/*檢查要修改的副檔名*/
try
{
if (SourceExt[0] != '.')
{
MessageBox.Show("請輸入含 '.' 的完整附檔名");
textBox1.Text = "";
return;
}
}
catch (Exception ex)
{ /*沒有輸入副檔名,表示要修改沒有副檔名的"檔案"*/ }


/*檢查要修改成的副檔名*/
try
{
if (NewExt[0] != '.')
{
MessageBox.Show("請輸入含 '.' 的完整附檔名");
textBox1.Text = "";
return;
}
}
catch(Exception ex) //沒有輸入要修改成的副檔名沒有意義
{
MessageBox.Show("請輸入副檔名");
return;
}


/*執行批次作業*/
foreach (FileInfo fi in di.GetFiles())
{
string name = fi.Name; //取的檔案的全名
string ext = fi.Extension; //取得檔案的附檔名
                string main = Path.GetFileNameWithoutExtension(fi.DirectoryName+"\\"+fi.Name) ;    //取得檔案的主要名

if (ext != ".exe" && ext !=".pdb" && ext!=NewExt && ext ==SourceExt)
{

/*更改副檔名*/
String NewName = main + NewExt;
fi.MoveTo(Path.Combine(fi.DirectoryName, NewName));
}
else
{ }

}//end_of_foreach

MessageBox.Show("修改完成!");

}//end_of_button_click

}
}

LINQ to SQL 增刪改

假設今天要更新一筆 Table tb(int No, string Name, string Favorite_Song) 中的資料呢?

 
  var tmp = new tb
  {
   tmp.No = 1,
   tmp.Name = “Veck",
   tmp.Favorite_Song = “Amazing Grace"
  };
 
  tb.InsertOnSubmit(tmp);   //在.NET 3.5 是 tb.Add(tmp);
  this.SubmitOnChange();    //一定要有這一行,不然資料會卡在記憶體,沒有寫入資料庫中


 var tmp = tb.single(c => c.No == 1);
 tb.DeleteOnSubmit(tmp);   //在.NET 3.5 是 tb.Remove(tmp);
 this.SubmitChange();

 
 var tmp = tb.single(c => c.No == 1);
 tmp.Name = “Kevin";
 this.SubmitChange();

*要稍微注意的是,如果要變動的資料表不只一個,或是有連動關係
有可能在更新的時候出現錯誤,但是資料某部分是有寫進去的
例如 tb1 和 tb2 以 No 做為 Foreign Key 連接,其中tb2為tb1的子資料表
今天若要新增一筆資料進tb2,必須先新增tb1一筆資料

var tmp = new tb1();
tmp.No = 2;
tb1.InsertOnSubmit(tmp);
this.SubmitChange();   //在這一行可能會出現錯誤,因為tb2中沒有同步新增 No = 2 的 Key

var tmp2 = new tb2();
tmp2.No = 2;
tb2.InsertOnSubmit(tmp);
this.SubmitChange();

 
var tmp = new tb1();
tmp.No = 2;
tb1.InsertOnSubmit(tmp);
var tmp2 = new tb2();
tmp2.No = 2;
tb2.InsertOnSubmit(tmp);
this.SubmitChange();      //差別在於只有在最後的時候才進行新增,這樣就不會有不同步的問題了

C# 與 LINQ 的 MVC 實踐

前幾天在看維基百科介紹 Ruby 程式語言的時候,看到Ruby on Rails 一個 MVC 的快速網站開發應用框架(Framework,在程式設計的領域是指一個提供該程式語言開發相關函數庫或是虛擬機器等等的環境),突然又出現一個縮寫名詞讓我忍不住轉而去查詢這個縮寫的意思,根據偉大的維基百科記載,MVC的全文是:Model-View-Controller,是軟體工程上面的一種 軟體設計模式 (軟體架構),接著一看這三個名詞分別代表的意思:
ü   (模型Model) – 程式設計師編寫程式應有的功能(實作演算法等等)、資料庫
   專家進行資料管理和資料庫設計(可以實作具體的功能)
ü   (檢視View) – 介面設計人員進行圖形介面設計。
ü   (控制器Controller)- 負責轉發請求,對請求進行處理。                                 (By Wiki – MVC)

過去對於這種抽象的概念我往往不是很能夠馬上理解,或是需要藉由開發的例子才能夠知道箇中意義,但是看著上述的簡單解釋,突然覺得很熟悉…。
對啦!這不就是類似微軟 .NET Framework 下的 LINQ to SQL 的設計方式嗎?再一次有種『過來人的經驗』的感受(第一次是上一次體會到LINQPEAR DB的相似),馬上往下拉視窗,尋找 ASP.NET MVC 的標籤,果不其然,上面就是如此寫著:ASP.NET MVC中,一般情況下模型通常搭配 LINQ to SQL 型別
對於這三個的解釋我以過去開發系統時採用LINQ to SQL的例子做說明,首先要講一下整個目前的企業開發系統所採用的『三層式架構』:
 (感謝K-STAR公司陳課長的指導)



        目前最常採用的系統設計會採用三層式架構,也就是由使用者介面、企業邏輯、資料庫三者連結而成的,使用者可以透過UI與系統互動,但是UI只負責與使用者互動並傳遞使用者改變的相關參數到下一層的企業邏輯去,由邏輯曾進行邏輯運算,而邏輯運算的廣大資料基礎便是建置在企業內部或是雲端上的資料庫、是資料倉儲、資料中心。
        UI和資料庫很容易區別,但是對於傳統寫網頁的人員而言,可能會和我一開始碰到『邏輯層』時一樣,不明白區別在哪裡,這個概念,其實就是MVC的實踐,可以用一個概念來思考:『UI就是版面設計,Logic就是程式設計』。
        很多時候,人們會把做『網頁設計』的想成一定就是『版面+程式』都要會,其實不然(雖然很多網頁設計人才是兩樣兼備),版面和程式是可以分開的,版面是程式的與外界的『互動表現(Representation)』,而程式才是整個網頁互動的基礎,所有互動的參數傳遞、資料運算、回饋、資料呈現、資料抓取等等都是由程式負責,而這個工作其實很大部分是沒有表現出來的,舉例來說,版面就是打開瀏覽器,看到畫面上GoogleLogo和下面的輸入框及搜尋按鈕,而當你按下搜尋,網頁會送出你輸入的值,傳送給一個檔案,由那個檔案負責做Search的運作,沒錯!那個檔案就是程式。
        有時候因為網站的互動功能較少,或是為了做功能上的區隔,會將UILogic寫在同一個檔案(很多PHP網頁即是如此),所以才會有『網頁(程式)設計就是整個網頁(也就是UI)』的錯覺,MVC就是把程式與美工做一個區隔,讓『版面人員專心做版面,程式設計師專心寫程式』。
        以 LINQ to SQL 來看,*.aspx (*.asp) 就是網頁的外觀設計(View),而*.cs就是檢視器(Controller),而繼承LINQ to SQL(*.dbml)*.cs檔案就是模型(Model),模型中定義各個可能的功能操作,甚至我覺得連*.aspx*.cs也可以看做是一個模型,因為你也可以在其中定義一些操作。
*補充維基百科上面講到RoRMVC模式:
Ruby on Rails 是透過 Ruby 語言所開發出來的 Web Framework,也是採用 Model-View-Controller 架構。Model 部份使用 Active Record 概念實做,加上 Migration 機制,使得其 Model 結構非常容易控制。

C# 不使用 SqlDataSource 連接資料庫

話說在學習 ASP.NET 的時候,因為初學的關係,所以許多教材都會教導使用 sqlDataSource 這個控制項來設定連接資料庫,好處是可以不用自己去 call  C#中呼叫資料庫的方法和免去輸入SQL語法的麻煩,另一個好處是可以直接使用 ASP.NET 提供的登入控制項,繫結資料庫做到登入驗證。

但是使用登入控制項的缺點,就是會受限於 ASP.NET 的格式化限制,也就是你不能夠自由的改變登入控制項的外貌(只有幾個樣式可以選擇),這個時候如果想要自己實作登入控制項,像是 PHP 那樣使用 HTML 的 Input-Text 和 Input-Button ,就沒辦法直接使用 sqlDataSource 繫結資料庫,首先我這邊先介紹如何在 ASP.NET 中不使用 SqlDataSource 連接資料庫,以下是我上網找了些資料以後測試成功的連接方法。

1. 建立一個 WebForm (WebForm1.aspx),並在 App_Data 中建立一個 SQL Server 資料庫檔案(Datebase1.mdf)

2.接著開啟程式碼 WebForm1.aspx.cs,並加入 using System.Data.SqlClient 這個命名空間,這個是 C# 提供連接資料庫的一個命名空間,後面所實體化出來的 SQL 物件都是在這個命名空間中的類別

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;      //加入這一個命名空間
namespace WebApplication1
{
    public partial class WebForm1 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
    
        }

    }
}
3. 在 Page_Load 事件中加入連接的
        protected void Page_Load(object sender, EventArgs e)
        {
            const string connect = @"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database1.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True“;     // *1 設定要連接的資料庫訊息
            SqlConnection conn = new SqlConnection(connect);    
           //建立一個SQL連接物件,類似PHP: mysql_connect()

            conn.Open();       //開啟連接
            string sqlstr = “select * from Table1″;     
            //SQL的語法就是在這邊寫囉!!! 類似PHP: mysql_query()

            SqlCommand cmd = new SqlCommand(sqlstr, conn);   
            //建立可以下SQL語法的物件
            SqlDataReader dr = cmd.ExecuteReader();    
          //SqlDataReader 是用來讀取下 SQL 語法之後查詢到的資料


            while (dr.Read())   //使用SqlDataReader的方法來讀取內容
             {                          //類似PHP : mysql_fetch_row(), .._arrays()
            
                Response.WriteLine(“編號:" + dr[“No"]);
                Response.WriteLine(“姓名:" + dr[“Name"]);
            }
 /*最後要記得關閉和釋放資源,不然之後還要再做不同的查詢,會出現錯誤喔!*/
            cmd.Cancel();  
            dr.Close();
            conn.Close();
            conn.Dispose();
        }