# MyORM Framework
## Introduction
- MyORM là ORM framework
- Các chức năng chính của MyORM
+ Kết nối tới nhiều cơ sở dữ liệu
+ Kết nối CSDL
+ Thao tác insert
+ Thao tác update
+ Thao tác delete
+ Thao tác select dữ liệu có where, group by, having
+ Đóng kết nối CSDL
## Implement
- Cách 1: Để implement MyORM bạn có thể install từ nuget package tại đường dẫn: https://www.nuget.org/packages/TuMeo.MyORM
- Cách 2: Các bước cài đặt
Bước 1: Tạo 1 project sử dụng .Net. Trong hướng dẫn này mình sử dụng Console app (.Net Framework)

Bước 2: Thêm package từ **Manage NuGet packages** trong add của project

Bước 3: Tìm kiếm 'TuMeo.MyORM' để install package

Bước 4: Chọn install để hoàn tất

<br>
## Useage
- Chúng ta có 1 table là "SinhVien" như sau
| ID | Name | GPA | CreateAt |
| --- | ------------ | ---- | -------- |
| 1 | Nguyễn văn A | 10.0 | 1/1/2020 |
| 2 | Nguyễn văn B | 5.0 | 1/1/2020 |
| 3 | Nguyễn văn C | 7.5 | 1/1/2020 |
- Để thực hiện truy vấn đầu tiên chúng ta sẽ phải tạo các class cho các table mà chúng ta muốn truy vấn, Ví dụ cho table "SinhVien":
```java
[TableAttribute("sinhvien")]
class SinhVien
{
[PrimaryKeyColumn("id", PrimaryType.AutoIncrement)]
public int ID { get; set; }
[Column("name")]
public string name { get; set; }
[Column("gpa")]
public double DTB { get; set; }
[Column("createat")]
public DateTime createAt { get; set; }
}
```
- Lưu ý về các "Attribute" sử dụng
+ Mỗi table sẽ tạo thành 1 class. Trước mỗi class phải sử dụng **TableAttribute(TableName)**
+ Đối với khóa ngoại sẽ sử dụng **PrimaryKeyColumn(PrimaryName, PrimaryType)**. PrimaryType là e enum có 1 loại là **None** và **AutoIncrement**
+ Mỗi Column sẽ tạo thành property. Trước mỗi property phải sử dụng **Column(TableName)**
- Kết nối tới cơ sở dữ liệu
```java
IDatabase database = new ConfigBuilder()
.SetDatabaseType(DatabaseType.MySQL)
.SetServer("127.0.0.1")
.SetDatabase("company")
.SetUserId("root")
.SetPassword("0978966563").Build();
```
- Thực hiện query
```java
IDatabase database = new ConfigBuilder()
.SetDatabaseType(DatabaseType.MySQL)
.SetServer("127.0.0.1")
.SetDatabase("company")
.SetUserId("root")
.SetPassword("0978966563").Build();
List<SinhVien> data = database.
GetQueryBuilder<SinhVien>().
SelectAll().
Where(x => x.DTB == 10).
Get();
```
### 1. SelectAll
- Mô tả: Tạo câu truy vấn Select From
- Implement:
```java
SqlString<SinhVien> sqlString = new SqlString<SinhVien>();
sqlString.SelectAll()
Console.WriteLine(sqlString.sql);
```
### 2. Insert(T obj) vs Insert(T[] arr)
- Mô tả: Tạo câu truy vấn Insert into
- Implement:
```java
SqlString<SinhVien> sqlString = new SqlString<SinhVien>();
sqlString.Save(new SinhVien(..)); // Chèn 1 dòng trong database
SinhVien[] arrSV = { new SinhVien(..), new SinhVien(..) , new SinhVien(..)}; // Chèn nhiều dòng
sqlStringSave(arrSV);
Console.WriteLine(sqlString.sql);
```
- Note : Cần thiết lập id tăng dần trong database
### 3. Update(T object)
- Mô tả: Tạo câu truy vấn Update trong database
- Implement:
```java
sqlString.Update(sinhVien).Where(sv => sv.ID == 1);
Console.WriteLine(sqlString.sql);
```
- Note : Sẽ cập nhật tất cả các trường trong đối tượng.
### 4. Where
- Mô tả: Tạo câu lệnh điều kiện.
- Implement:
```java
sqlString.SelectAll().Where(sv => sv.name == "ss dfd").AND(sv => sv.DTB >= 5);
Console.WriteLine(sqlString.sql);
```
- Note :
- Sử dụng operator "==" đối với các trường kiểu String sẽ được chuyển sang "LIKE" trong sql, đối với các trường còn lại sẽ được chuyển thành "=".
- Để thêm nhiều điều kiện ta sử dụng thêm AND(),OR();
### 5. Delete()
- Mô tả: Tạo câu lệnh Delete.
- Implement:
```java
sqlString.Delete().Where(sv => sv.DTB >= 5);
Console.WriteLine(sqlString.sql);
```
### 6. GroupBy()
- Mô tả: Tạo câu lệnh GroupBy. Cho phép Client group by dữ liệu từ table theo 1 column
- Implement:
```java
Dictionary<int, List<SinhVien>> data = database.
GetQueryBuilder<SinhVien>().
GroupBy(x => x.DTB).GetGroupby<int>();
foreach (var item in data)
{
Console.WriteLine(item.ToString());
}
```
- Chú ý: Cần phải truyền đúng kiểu của group vào hàm ```GetGroupBy<T>()```
Ví dụ: Ở đây chúng ta gropby theo ID có kiểu dữ liệu là interger nên chúng ta phải truyền vào là int
```java
Dictionary<int, List<SinhVien>> data = database.
GetQueryBuilder<SinhVien>().
GroupBy(x => x.DTB).GetGroupby<int>();
```
### 7. Having()
- Mô tả: Tạo câu lệnh Having. Cho phép Client Having tạo điều kiện cho câu lệnh groupby
- Implement:
```java
Dictionary<double, List<SinhVien>> data = database.
GetQueryBuilder<SinhVien>().
GroupBy(x => x.DTB).
Having(x=>x.AVG(x.Value.DTB)>50).
GetGroupby<double>();
foreach (var item in data)
{
Console.WriteLine(item.ToString());
}
```
- Having chỉ hỗ trợ sử dụng điều kiện bằng các Hàm **Count(),MIN(x.Value.xx), MAX(x.Value.xx) ,SUM(x.Value.xx), AVG(x.Value.xx)**
+ xx là các thuộc tính của class cần group by