# ADO.Net筆記
## 0. Introduction
## 0.1 建議字體改字體防止字型分不清楚
JetBrain mono
Source Code pro
## 0.2 自修方法
### 找sample題目自己練習:
關鍵字:經典100題,c語言經典100題


### 找電子書amazon.cn
第一次買需要vpn,中國美國是分開的
### 找電子書HyRead
桃園電腦書多
國家圖書館也可以
## 0.3 行業與技術推薦
銀行 storedProcedure
一般公司 dapper(不用寫參數和轉物件 有內建),EF
老公司 ADO.Net
科技業WinForm
## 1. MSSQL資料庫操作
### 1.1 C#連線資料庫的三種方式
三種主流:
ADO.NET <= T-SQL
Entity FrameWork <= 加上LINQ
Dapper
ADO.NET = 取資料,可自己加
LINQ = 高級語法,用ORM的方式幫你生SQL語法和呼叫ADO.NET取資料,缺點部分品牌的資料庫法無法轉成.NET的資料集
### 1.2 建立MSSQL權限


## 1.3 建資料表的主鍵
- 唯一識別打開,欄位設為索引



### 1.4 不允許變更,要取消
工具>選項>設計師 取消打勾





### 1.5建立外鍵

### 1.6設定唯一鍵

### 1.7 設計反正規化
照道理不應該有,但你還是建立,例如訂單table的訂單總金額,雖然每個,但為了分析總金額前3的訂單,只要有紀錄3秒鐘,沒有的話5分鐘。
記錄當下那瞬間承諾了甚麼,例如product過年有贈品,但之前買的人會哭怎麼沒送,所以還是要在orderItems的要給一個column紀錄。
例如我要找訂單order的供應商,我必須正規化join很多表單才拿得到資料,可以考慮新增欄位反正規化。
更新原則與刪除原則。
關聯no action,cascade(重疊顯示 串接刪除),
## 2. 專案練習
### 2.1連線字串產生網站
[connectionstring連線字串網站](https://www.connectionstrings.com/microsoft-data-sqlclient/)
#### 連線字串加入app.Config
```csharp=
<connectionStrings>
<add name="default" connectionString="Server=.; Database=ADOpractice_20230103;User Id=sa5;Password=sa5;" />
</connectionStrings>
```
#### 加入組件system.Configuration

Trusted Connection公司內部的AD,登入內部的AD,AD再用信任連結。
Winform寫在APP.config
asp.netMVC5寫在web.config
asp.net core mvc:appsettings.json
#### 補充: 允許空值NULL的語法

### 2.2 好工具sql server profiler
看看別人打了什麼sql語法進來。
在ssms中的工具選單叫出
### 2.3允許連線可用sql server方式

因為安裝時沒有設定帳號密碼,就用window本機連線
### 2.4 Alt+Enter智慧提示修正錯誤


### 2.5小技巧們
#### ado.net比較好管理的寫法

#### winform檢視:定位順序

### winfrom建構子語法糖

### 2.6泛型擴充方法與DBNull與泛型資料型態的預設值
```csharp
public static class SqlDataReaderExtension
{
public static G GetFieldValue<G>(this SqlDataReader source, string columnName)
{
// 每個泛型資料型態的預設值,例如int的預設值=0,bool的預設值是false
// T defaultValue = default;
// DBNull是看看db的值是不是null,
return source[columnName].Equals(DBNull.Value)
? default(G)
: (G)source[columnName];
}
}
```
### 靜態class
1. 不能繼承
2. 裡面不能有非靜態的method和property
### 刪除tab比較快

### return List or Array?
回傳IEnumerable<>包含泛型就可以了
DTO通常不會寫驗證,單存儲存property
DTO:DATA Transfer object
### 人工收合程式碼

### 反斜線a會叫

### @ 可以多行、反斜線path引入

### read是讀指標

### yield return

### sql injection
字串用組的,難免有人會輸入惡意程式碼。

只要有找到資料算登入成功?

### 時間使用的錯誤範例

### 防止SQL Injection

### 百元買百雞
公雞 5元
母雞 3元
小雞 3隻1元
### 新增params


### 字典式教學
1. 給別人看你寫的,看看有沒有內建的method
2. 練題目,寫得出來,但沒人檢討QQ
3. MSDN找功能
## ADO.NET的SQL-CRUD方法
### Create
```csharp=
public static int Create(News entityNews)
{
SqlDB.ApplicationName = "save_createNew";
// SQL參數化
string sql = $@"insert into News
(title, Description, CreateTime, ModifiedTime)
VALUES(@title, @Description, @CreateTime, @ModifiedTime)
SET @newId = SCOPE_IDENTITY()";
//SqlParameter[] parameters = new SqlParameter[] {
// new SqlParameter("@title",System.Data.SqlDbType.NVarChar, 58 ){ Value = entityNews.title },
// new SqlParameter("@Description", System.Data.SqlDbType.NVarChar, 3000) { Value = entityNews.description },
// new SqlParameter("@CreateTime", System.Data.SqlDbType.DateTime) { Value = entityNews.createdTime },
// new SqlParameter("@ModifiedTime", System.Data.SqlDbType.DateTime) { Value = entityNews.updatedTime },
// new SqlParameter("@newId", System.Data.SqlDbType.Int) { Direction = System.Data.ParameterDirection.Output},
//};
var parameters = SqlParameterBuilder.Create()
.AddNVarchar("@title", entityNews.Title, 58)
.AddNVarchar("@Description", entityNews.Description, 58)
.AddDateTime("@CreateTime", entityNews.CreatedTime)
.AddDateTime("@ModifiedTime", entityNews.UpdatedTime)
.AddInt("@newId", null,System.Data.ParameterDirection.Output)
.Build();
using (SqlConnection conn = SqlDB.GetConnection("default"))
{
using (var command = conn.CreateCommand()) {
conn.Open();
command.CommandText = sql;
command.Parameters.AddRange(parameters);
command.ExecuteNonQuery();
return (int)command.Parameters["@newId"].Value;
}
}
}
```
### Read
```csharp=
public Category GetCategory(int categoryId)
{
Category category = null;
SqlDB.ApplicationName = "getCategory test";
// SQL連線會忘記斷資源所以用using
using (SqlConnection conn = SqlDB.GetConnection("default"))
{
string sql = $"select * from Categories where Id = {categoryId}";
var command = new SqlCommand(sql, conn);
conn.Open();
// 空一行看起來舒服,{System.Data.SqlClient.SqlDataReader} reader
using (var reader = command.ExecuteReader())
{
if (reader.Read())
{
category = Category.GetInstance(reader);
}
}
}
return category;
}
```
```csharp=
```
```csharp=
```
### Update
```csharp=
public static int Update(News entityNews)
{
SqlDB.ApplicationName = "save_createNew";
// SQL參數化
string sql = $@"update News set
title = @title,
Description = @Description,
ModifiedTime = @ModifiedTime
Where Id = @Id";
var parameters = SqlParameterBuilder.Create()
.AddNVarchar("@title", entityNews.Title, 58)
.AddNVarchar("@Description", entityNews.Description, 58)
.AddDateTime("@ModifiedTime", entityNews.UpdatedTime)
.AddInt("@Id", entityNews.Id)
.Build();
using (SqlConnection conn = SqlDB.GetConnection("default"))
{
conn.Open();
using (var command = new SqlCommand(sql, conn))
{
command.Parameters.AddRange(parameters);
return command.ExecuteNonQuery();
}
}
}
```
```csharp=
```
### Delete
```csharp=
```
### 包成公用

### 聚合函數
```csharp=
public static int GetCountOfTable(string tableName, int categoryId)
{
SqlDB.ApplicationName = "getCategory test";
// SQL連線會忘記斷資源所以用using
using (SqlConnection conn = SqlDB.GetConnection("default"))
{
string sql = $"select * from {tableName} where Id = {categoryId}";
// 某個SQL command的連線
using (var command = new SqlCommand(sql, conn))
{
conn.Open();
object result = command.ExecuteScalar();
return Convert.ToInt32(result);
}
}
}
```
### 神奇的包函數for委派

### 自動折行 不要讓程式碼跑到螢幕之外

### 切fucntion 技巧
5~10行或者1個畫面超過就切function
function的引入參數不要超過3個
### winForm的事件
cellClick 按到cell就有
cellContentClick 按到cell的文字才有
### class欄位常數與private readonly的差別

### 子表單傳資料回母表單
#### 方法1
1. 多重表單呼叫會忘記誰叫他
2. this傳過去是傳form,form底下沒有Display的方法 要轉型!

有介面才實作這個方法,null就不管,可減少相依性
ps.介面的方法要public

最好的方法是用event
### 快速抽出function

### InnerException

### 檢查錯誤

### 寫程式快捷鍵
1. 按shift可以切換大小寫
2. ALT + 上下鍵可以
3. 註解Ctrl + k + c
4. 取消註解Ctrl + k + u
5. 選取單字,Ctrl+Shift往左 可以選取左邊的單字
#### 軟體推薦
SnagIt 截圖軟體
### 想法:資料表的class產生器
可以應用在partial class去產生程式碼
再用partial class手動補充
level.1
1. 從db抓出所有欄位
2. 把欄位資訊存成記事本,副檔名.cs
3. 就自動產生了class
level.2
在記憶體及時產生,就看不到程式碼了
### 作業檢討注意
1. 介面實作了什麼要講得出來
2. sql大寫 SELECT*FROM table
3. 命名注意不要衝到class
4. 欄位是create time的時候要注意不要update到!!!
5. 目前學習模式是範本複製貼上學習模式,應該養成自己看懂後默寫習慣。
## 三層式架構
為何資料驗證和商業邏輯驗證分開,因為瀏覽器回應時間,資料驗證和商業邏輯驗證寫在BLL層,等待回應時間過久。都寫在ui層若換介面例如主控台、WinForm、MVC就不行惹。
Dto和Entity的差異?是Dto可以亂傳東西? 小網站可簡化Dto當作Entity
先busniessRule再存Entity吧? 都可以
單元測試寫在busniessRule,因為最容易錯。
優點:
若寫在單一檔案多method易衝突,3層式比較不會衝突
單一職責
需要小method可以勇敢寫
優點:大流量每個表單可以分給每個查詢用DB去查,insert的db再複寫到查詢的db,用class分開寫有彈性易改。
補充:查詢和command的db分開。


給不同人用的就不要re use了。
人類需求的功能轉成程式功能之間的落差
### errorProvider

### 從專案移除

### story強型別的資料庫技術
原本db要雙引號引入資料,但現在只要.欄位就好。
微軟出新技術不一定馬上跟,因為新東西試要很久時間。
找資料多的先學,效率比較高。
學習慢,但深入。所以老技術慢慢演變。
## 主程式表單
### Meau s


### Login 頁面
MaixmaBOX = false <<<表單不能放大
FormBorderStyle: Fix3D <<<表單不能被任意放大
startPosition:CenterScreen
### main 頁面
最小size

ancor :right down,會自動跟著右下延伸
### 匿名物件用var

### winform表單欄位改中文



## 剪刀石頭布遊戲:抽象方法
剪刀石頭布(3種case)
資料結構:循環鏈結
若棒打老虎雞吃蟲(4種case): 若用兩層if = 4*4 = 16
循環鏈結 4*2 = 8
## 扭蛋機:狀態模式
當遇到物件有很多狀態或者操作
例如訂單Order object,有出貨退貨修改等等,例如修改訂單要根據狀態而定,若狀態已出貨結案就不能了,若還沒出貨就不能退定(請物流收)。




### 新增方案資料夾

### 衛述句:不要把很長的程式碼包在if裡面

### 假的

## 屬性限制
中括號是屬性限制

### 若有join可以直接呼叫db層!!!!!?!

## 小故事
- 微軟entity framework連Oracle比較慢,
- 保密協定,1天1萬,美其名不能教別人,因為怕你把別人教壞。
- 斷電,打開word新增檔案,存檔!
- 廠商不給原始碼,資料庫密碼太簡單寫在.cs而不是config,所以無法改。
- 秘書土地謄本:碎碎念模式與大概模式
- 小故事:董事長不懂程式RD主管不改,直接駭掉SQL injection,
- 小故事:老師的打字速度不一定快,但老師可以帶領所有人的coding變更好。
- 一天收入1萬塊 薯條點大薯、布丁不舔蓋子
- 賣麵、去果園摘水果再開車去賣給市場。 上班族領最少,但其他風險高。
- 接案想法小故事ZUSH人員序號,gdzc建檔日期,ZUD人員檔
- 總共50萬,25萬接,寫完程式不要讓員工被老闆Fire掉,IF員工講錯漏講都不用加錢,如果說老闆說要,那就要加錢。跟窗口做朋友,系統上線其他同事反應可以幫忙擋。老師不會寫,叫他寫。
- 如果看到method超過一個螢幕,就應寫成method。糊糊的一坨一坨。
- 複製貼上再小改就是錯誤的開始。
- 小故事:一個會寫程式的,加個紅利範圍就GG,寫1個月改2個月,後來決定不要這功能了。改這裡也錯,那裏也錯,要大家互相配合。
- 小故事 若沒有講價格,先做,客戶嫌貴,那就不要付。1.客戶不付 2.客戶給另外的案子。若是遇到奧客約好30萬但又說我用不到,15萬要不要,就要吧。或者預付每個月1萬,但公司的人離職了哈。
- 若案子100萬,抓30%維護費1年,報價130萬。25萬外包給8000,4萬給4百,1萬5千給100。

- 時間到,程式沒出來,叫菜鳥拿第一頁壞掉的檔案過去。
- winform能不能畫面歪10度? 原來是螢幕也歪10度了。
- 手機偵測保護殼的顏色。apple磁吸得據說有。
- 小故事:等人家教就比較慢。老師學序列化。學正規表達所有書沒有,只有別的語言java才有,讀c#的原文書才有詳細講解。
- sqlServer不得了,不論多快的電腦都一樣快
q1請老師教如何開放資料庫給大家連,但是又安全的基本方式。
每個DB帳號對應一個DB權限。
q2資料庫怎麼備份,每天存一個檔出去?
差異備份、只備份變更檔與起始的DB檔案。
q3. 到處try catch
reUse exception
q4. db資料驗證
q5.join跳過businessRule要怎麼管理?(直接跳過的話)
q6.談需求。小專案瀑布求重用性,長時間大專案敏捷求可擴充性。
給不同人用的就不要re use了。
人類需求的功能轉成程式功能之間的落差
Q7 每次ado.net都要重新定義資料好累?you need dapper & EF
心得:人際的好壞?接案的順利性QQ
AllenKuo youtube
https://www.youtube.com/c/AllenKuoCode4Fun
---
###### tags: `c#筆記`