---------------------- Windows Phone 7手機開發、.Net培訓、期待與您交流! ------------------
小小的感想:越是長大,發現時間走得也越快,這兩年過得比以往任何時候都快,最大的收穫就是找到了職業方向,那就是做一名優秀的.net程序員,這個目標在去年12月份就已經確定了,雖然一直在學視頻,真正投入的卻不多,每天不是早上五點多起牀,就是凌晨四五點睡覺,根本沒多少時間,而且上完班確實累,所以完全不在狀態,就這樣過了幾個月,雖然把視頻全部看完而且把視頻上的代碼跟着敲了一遍,事實上並沒有掌握多少。上班的時候總是想着,一定要把握好下班後的每一時每一刻,下班後聽聽音樂看看空間什麼的一過又是幾個小時,接下來累了又想休息,想等以後進了黑馬就可以全心全意投入了。今天很快就要過去,明天很快就要到來,等待你的不是別的,是流水線。長達十小時的流水線,因爲對自己的屢屢食言,我終於不再相信自己,不相信一個把握不好現在的人,能把握好未來。現在要做的,就是把握現在,就算在工作,也要把沒有弄明白的代碼寫在紙上放在身邊,有空就看。七月底兩年的合同到期,在合同到期之前拿到黑馬的錄取通知書,是現階段的目標。
我不知道自己是否有天份做程序員,這一次我會盡自己最大的努力去把它學好,學精。
Ado.Net實現程序和數據庫的交互,爲各種不同的數據庫提供統一接口,實現應用程序和數據庫的聯接。
程序要通過聯接字符串指定要聯接哪臺服務器上的哪個實列的哪個數庫庫,用什麼用戶名密碼等,因爲程序默認會去連接Bin/Debug下的mdf文件,而不是項目中的mdf文件,所以當插入修改數據庫中的數據在運行程序後項目中數據庫的數據並不發生變化,爲了讓程序去連接項目中的mdf文件,而不是連接bin/Debug下那個要在Program.cs文件Main函數最開始加入如下代碼:
string dataDir = AppDomain.CurrentDomain.BaseDirectory;
if(dataDir.EndsWith(@"\bin\Debug\")
||dataDir.EndsWith(@"\bin\Release\"))
{
dataDir = System.IO.Directory.GetParent(dataDir).Parent.Parent.FullName;
AppDomain.CurrentDomain.SetData("DataDirectory",dataDir);
}
創建數據庫的聯接Connection conn= new SqlConnection(@” DataSource=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|\Database1.mdf;IntegratedSecurity=True”)
如果多次聯接而聯接發生變化時需要對每個聯接字符串進行修改很麻煩,有一種方法就是把連接子符串放到配置文件中,這樣只要修改配置文件中的數據就可以了。在配置文件中
<configuration>
<connectionStrings>
<add name="connstring" connectionString="連接字符串"/>
</connectionStrings>
</configuration>
然後添加引用System.Configuration
string strcoon = ConfigurationManager.ConnectionStrings["connstring"].ConnectionString;
將連接字符串放到變量strcoon中,用的時候就可以用變量strooon代替了。
數據的導入
思路:目的只有一個就是把文件中的數據導入到數據庫。首先要獲得文件路徑,獲得所有要導入的文件並取出文件中的數據。用Directory. GetFiles(stringpath, string searchPattern, SearchOption searchOption)獲取所有的文件,用一個foreach循環遍歷所有的文件file, Path.GetFileNameWithoutExtension(file)獲得文件名,File.ReadAllLines(file, Encoding.Default)提取文件中的數據,注意加上Encoding.ASCI,因爲文件中的數據爲ASCI碼,而程序運行的是UTF-8碼,否則會出現亂碼。
代碼如下:
public partial classForm1 : Form
{
publicForm1()
{
InitializeComponent();
}
private voidbtnimport_Click(object sender, EventArgs e)
{
FolderBrowserDialogfbdlg = new FolderBrowserDialog();
if(fbdlg.ShowDialog() != DialogResult.OK)
{
return;
}
stringpath = fbdlg.SelectedPath;
stringstrconn = ConfigurationManager.ConnectionStrings["strconn"].ConnectionString;
using (SqlConnectionconn = new SqlConnection(strconn))
{
conn.Open();
using(SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "delete from TablePhoneNumber";
cmd.ExecuteNonQuery();
}
}
string[]files = Directory.GetFiles(path, "*.txt", SearchOption.AllDirectories);
using (SqlConnectionconn = new SqlConnection(strconn))
{
conn.Open();
using(SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "insert intoTablePhoneNumber(startNumber,endNumber,name)values(@startNumber,@end,@address)";
foreach (string file in files)
{
string nameth.GetFileNameWithoutExtension(file);
string[] lines = File.ReadAllLines(file, Encoding.Default);
foreach (string line in lines)
{
string[] strs =line.Split('-');
string StartNumber= strs[0];
string EndNumber =strs[1];
string Address =strs[2];
cmd.Parameters.Clear(); cmd.Parameters.Add(newSqlParameter("startNumber", StartNumber));
cmd.Parameters.Add(newSqlParameter("end",EndNumber));
cmd.Parameters.Add(newSqlParameter("address", name+Adress));
cmd.ExecuteNonQuery();
}
}
}
}
MessageBox.Show("導入成功");
}
private voidbtnsearch_Click(object sender, EventArgs e)
{
stringstrconn = ConfigurationManager.ConnectionStrings["strconn"].ConnectionString;
using (SqlConnectionconn = new SqlConnection(strconn))
{
conn.Open();
using(SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "select * from TablePhoneNumber wherestartNumber<=@inputnumber and endNumber >=@inputnumber";
cmd.Parameters.Add(new SqlParameter("inputnumber",textBox1.Text));
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.Read())
{
string name =reader.GetString(reader.GetOrdinal("name"));
MessageBox.Show("號碼歸屬地:" + name);
}
else
{
MessageBox.Show("歸屬地未知");
}
}
}
}
}
}
導入到數據庫。
創建一個名爲Database1.mdf的數據庫,在數據庫添加一個名爲T_M的表,在表中有主鍵Id(自增類型),Name,Age。
輸出當前插入數據的Id的值:在Values前添加OUTPUT inserted.Id
INSERTINTO T_M(Name, Age) OUTPUT inserted.Id VALUES('wolf', 100)
首先創建數據庫聯接。
SqlConnection conn = new SquConnection(@"DataSource=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|\Database1.mdf;IntegratedSecurity=True");實現了IDisponse接口故可用Using(){}進行資源釋放。
打開數據庫聯接:conn.open();
創建查詢命令:SqlCommand cmd = conn.CreateCommand();
插入一條數據Cmd.CommandText= insert intoT_M(Name,Age) values (‘huangzhong’,24);
Cmd.ExecuteNonQuery();執行的不是查詢語句。
得到自增字段Id的值:INSERT INTO T_M(Name, Age) OUTPUT inserted.Id VALUES ('wolf', 100)
Cmd.ExecuteScalar()返回一個一行一列的Object類型的數據。
將其轉換爲Int類型輸出:int I = convert.toint32(Cmd.ExecuteScalar());
Console.writeline(“新插入數據的主鍵值Id爲”,i);
ExecuteScalar只返回單個列序列號,要執行有多行結果返回用ExecuteReader,reader的getstring,getint32等方法只接受Int參數,也就是序列號第幾列的值,用GetOrdinal方法根據列名動態獲得序號.就是根據列名(字段名)獲取序列號。如:
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{一個布爾類型的數據,只要有數據就會一條條往下讀,直到沒有數據返回False; Console.WriteLine(reader.GetString(1));讀取列號爲1的數據
Console.writeline(reader.getstring(reader.getordinal(“Name”));根據字段名獲取列號,再讀取顯示出來。
}
用Using釋放資源,內部會自動調用Close及Disponse,Close只是暫時關閉,還可以打開使用,Disponse則是銷燬無法再用了。
以下是一個登錄程序:
Console.WriteLine("please input your name");
stringusername = Console.ReadLine();
Console.WriteLine("pleaseinput key");
stringpassword = Console.ReadLine();
using (SqlConnectionconn = new SqlConnection(@"DataSource=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|\Database1.mdf;IntegratedSecurity=True"))
{ conn.Open();
using(SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "select * from mytable where UserName='"+username+"'";
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.Read())
{//如果用戶名存在
string dbpassword =reader.GetString(reader.GetOrdinal("Password"));
if (password ==dbpassword)
{
Console.WriteLine("登錄成功");
}
else
{
Console.WriteLine("密碼錯誤登錄失敗");
}
}
else
{用戶名不存在
Console.WriteLine("用戶名不存在");
}
}
}
}
Console.WriteLine("successopen data connection ");
Console.ReadKey();
還可以用另外一種方法,但是有漏洞,如果輸入密碼爲1 ’or’ 1 ‘=’1同樣可以登錄。
Console.WriteLine("please input your name");
string username = Console.ReadLine();
Console.WriteLine("pleaseinput key");
string password = Console.ReadLine();
using (SqlConnectionconn = new SqlConnection(@"DataSource=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|\Database1.mdf;IntegratedSecurity=True"))
{ conn.Open();
using(SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "select count(*) from mytable where UserName=usernameand Password =password”
int I = convert.toint32(cmd.executeScalar());
if(i)>0{console.writeline(“登錄成功“)
else{console.writeline(“用戶名或密碼錯誤“);
}
}
Console.WriteLine("successopen data connection ");
Console.ReadKey();
解決方法:用佔位符@name和@pass代替分別username和password賦值給UserName及Password,然後用參數傳遞。
將cmd.CommandText = "select count(*) frommytable where UserName=username and Password =password”改爲:
Cmd.commandText=”select count(*) from mytable whereUserName = @name and Password=@pass”;
cmd.Parameters.Add(new SqlParameter("name",username));
cmd.Parameters.Add(new SqlParameter("pass",password));
cmd.Parameters.Add(new SqlParameter("pass",(object)1);如果是常量則需要轉換爲Object類型。
爲了避免寫重複代碼,可以把ExecuteNoQUery,ExecuteScalar等進行封裝,在程序中只要調用主可以了,創建一個SQLhelp類,在類中進行封裝:
class SQLhelp
{
public staticint ExecuteNonQuery(string sql, params SqlParameter[] parameters)
{
stringconnstring = ConfigurationManager.ConnectionStrings["connstring"].ConnectionString;
using (SqlConnectionconn = new SqlConnection(connstring))
{
conn.Open();
using(SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = sql;
foreach (SqlParameter parameter in parameters)
{
cmd.Parameters.Add(parameter);
}
return cmd.ExecuteNonQuery();
}
}
}
public staticobject ExecuteScalar(string sql, params SqlParameter[] parameters)
{
stringconnstring = ConfigurationManager.ConnectionStrings["connstring"].ConnectionString;
using (SqlConnectionconn = new SqlConnection(connstring))
{
conn.Open();
using(SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = sql;
foreach (SqlParameter parameter in parameters)
{
cmd.Parameters.Add(parameter);
}
return cmd.ExecuteScalar();
}
}
}
public staticSqlDataReader ExecuteReader(string sql, params SqlParameter[] parameters)
{
stringconnstring = ConfigurationManager.ConnectionStrings["connstring"].ConnectionString;
using (SqlConnectionconn = new SqlConnection(connstring))
{
conn.Open();
using(SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = sql;
foreach (SqlParameter parameter in parameters)
{
cmd.Parameters.Add(parameter);
}
return cmd.ExecuteReader();
}
}
}
public staticDataTable ExecuteDataTable(string sql, params SqlParameter[] parameters)
{
stringconnstring = ConfigurationManager.ConnectionStrings["connstring"].ConnectionString;
using (SqlConnectionconn = new SqlConnection(connstring))
{
conn.Open();
using(SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = sql;
foreach (SqlParameter parameter in parameters)
{
cmd.Parameters.Add(parameter);
}
DataSet dataset = new DataSet();
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
adapter.Fill(dataset);
return dataset.Tables[0];
}
}
}
}
更新DataSet的數據:可以更新行row[“Name”]=”Ariel”,刪除行dataTable.Rows.Remove(),新增行dataTable.NewRow()。這些操作都只是修改內存中的DataSet,並沒有修改數據庫中的數據。
要修改數據庫中的數據要調用SqlDataAdapter的Update方法對DataSet的修改提交到數據庫。Updata方法有很多重載,可以提交整個DataSet,DataTable,或若干個DataRow,但是需要爲SqlDataAdapter提供UpdateCommand,InserCommand,UpdateCommand才知道如何將DataSet的修改提交到數據庫,可以用SqlCommandBuilder自動生成這幾個Command,用法:SqlcommandBuilder builder =new SqlCommandBuilder(adapter)
C#中值類型是不能爲空的,只要在類型後加?就構成了可空的數據類型,如:Int類型數據是不能爲NULL的,int?表示可空的int。
弱類型DataSet的缺點:只能通過列名來引用,寫錯了編譯不會發現錯誤,必須記住列名,從DataSet中取來的的數據類型都是Object類型,,使用時要進行類型轉換麻煩且容易出錯。將DataSet傳遞給其它使用者,使用者很難識別哪些列可以使用,運行時才能知道所有列名,數據綁定麻煩。
因此,我們可以自己動手寫強類弄DataSet,即類型化DataSet。封裝屬性和方法等直接調用。
強類型DataSet的創建方法,建一個數據集,將表拖到數據集中就創建了一個強類型DataSet。
用法:首先New一個TabeAdapter,表名+TableAdapter adapter=new表名+TableAdapter();
表名+DataTable datatable = adapter.getData();
----------------------- Windows Phone 7手機開發、.Net培訓、期待與您交流! ---------------------- 詳細請查看:http://net.itheima.com/