#### Hàm XPath

##### Công dụng:

Hàm XPath được sử dụng để truy vấn thông tin từ một tài liệu XML.

##### Cấu trúc hàm:

`public XmlNode? XPath(string xpathExpression)`

##### Tham số:

xpathExpression: Một chuỗi XPath để truy vấn tài liệu XML.

##### Kết quả trả về:

Một đối tượng XmlNode chứa kết quả truy vấn hoặc null nếu không tìm thấy.

##### Ví dụ:

###### 1. Truy vấn thông tin MA_LK:

`XmlNode? node1 = XPath("//MA_LK");`

Giá trị của `node1` sẽ là nút XML chứa thông tin MA_LK.

###### 2. Truy vấn thông tin MA_DICH_VU:

`XmlNode? node2 = XPath("//MA_DICH_VU");`

Giá trị của `node2` sẽ là nút XML chứa thông tin MA_DICH_VU.

###### 3. Truy vấn thông tin MA_BAC_SI:

`XmlNode? node3 = XPath("//MA_BAC_SI");`

Giá trị của `node3` sẽ là nút XML chứa thông tin MA_BAC_SI.

#### Hàm XPaths

##### Công dụng:

Hàm XPaths được sử dụng để truy vấn nhiều nút thông tin từ một tài liệu XML.

##### Cấu trúc hàm:

`public XmlNodeList? XPaths(string xpathExpression)`

##### Tham số:

xpathExpression: Một chuỗi XPath để truy vấn tài liệu XML.

##### Kết quả trả về:

Một đối tượng XmlNodeList chứa danh sách các nút truy vấn hoặc null nếu không tìm thấy.

##### Ví dụ:

###### 1. Truy vấn danh sách thông tin MA_LK:

`XmlNodeList? nodes1 = XPaths("//MA_LK");`

Giá trị của `nodes1` sẽ là danh sách các nút XML chứa thông tin MA_LK.

###### 2. Truy vấn danh sách thông tin MA_DICH_VU:

`XmlNodeList? nodes2 = XPaths("//MA_DICH_VU");`

Giá trị của `nodes2` sẽ là danh sách các nút XML chứa thông tin MA_DICH_VU.

###### 3. Truy vấn danh sách thông tin MA_BAC_SI:

`XmlNodeList? nodes3 = XPaths("//MA_BAC_SI");`

Giá trị của `nodes3` sẽ là danh sách các nút XML chứa thông tin MA_BAC_SI.

#### Hàm Sum

##### Công dụng:

Hàm Sum được sử dụng để tính tổng các giá trị số của một trường cụ thể trong danh sách các nút XML.

##### Cấu trúc hàm:

`public static decimal Sum(this XmlNodeList nodeList, string field)`

##### Tham số:

- nodeList: Một danh sách các nút XML.
- field: Tên trường cần tính tổng trong danh sách nút XML.

##### Kết quả trả về:

Một số thập phân là tổng các giá trị của trường cụ thể trong danh sách nút XML.

##### Ví dụ:

###### 1. Cơ bản: Tính tổng các giá trị của trường "THANH_TIEN":

`decimal totalAmount = nodeList.Sum("THANH_TIEN");`

Giá trị của `totalAmount` sẽ là tổng các giá trị của trường "THANH_TIEN" trong danh sách nút XML.

###### 2. Kết hợp: Tính tổng và lưu vào biến thông qua hàm khác:

`public static void CalculateTotal(XmlNodeList nodeList) { decimal total = nodeList.Sum("THANH_TIEN"); // Lưu giá trị total vào database hoặc thực hiện các thao tác khác }`

Ở đây, chúng ta tính tổng và sau đó có thể lưu nó vào cơ sở dữ liệu hoặc thực hiện các thao tác khác.

###### 3. Phức tạp: Kết hợp với LINQ để tính tổng theo điều kiện:

`decimal totalFilteredAmount = nodeList.OfType () .Where(x => x.SelectSingleNode("MA_NHOM").val().ToInt() == 1) .Sum(x => x.SelectSingleNode("THANH_TIEN").val().ToDecimal());`

Ở đây, chúng ta chỉ tính tổng các nút có `MA_NHOM` là 1.

#### Hàm length

##### Công dụng:

Hàm length được sử dụng để lấy số lượng các nút XML trong danh sách.

##### Cấu trúc hàm:

`public static int length(this XmlNodeList nodeList)`

##### Tham số:

- nodeList: Một danh sách các nút XML.

##### Kết quả trả về:

Một số nguyên là số lượng các nút XML trong danh sách.

##### Ví dụ:

###### 1. Cơ bản: Lấy số lượng các nút XML:

`int count = nodeList.length();`

Giá trị của `count` sẽ là số lượng các nút XML trong danh sách.

###### 2. Kết hợp: Kiểm tra số lượng trước khi thực hiện thao tác:

`if (nodeList.length() > 0) { // Thực hiện thao tác }`

Ở đây, chúng ta chỉ thực hiện thao tác nếu có ít nhất một nút XML trong danh sách.

###### 3. Phức tạp: Kết hợp với LINQ để lọc các nút theo điều kiện:

`int filteredCount = nodeList.OfType () .Where(x => x.SelectSingleNode("MA_NHOM").val().ToInt() == 1) .ToList() .length();`

Ở đây, chúng ta chỉ đếm số lượng các nút có `MA_NHOM` là 1.

#### Hàm val

##### Công dụng:

Hàm val được sử dụng để lấy giá trị thực sự của đối tượng, đặc biệt là các đối tượng có kiểu là StringField, DecimalField, IntField, và XmlNode.

##### Cấu trúc hàm:

`public static object? val(this object value)`

##### Tham số:

- value: Đối tượng cần lấy giá trị.

##### Kết quả trả về:

Giá trị thực sự của đối tượng đầu vào.

##### Ví dụ:

###### 1. Cơ bản: Lấy giá trị của StringField:

`StringField strField = new StringField("Hello"); object val1 = strField.val();`

Giá trị của `val1` sẽ là "Hello".

###### 2. Kết hợp: Sử dụng trong một hàm tính tổng:

`public static decimal SumValues(List fields) { return fields.Sum(field => (decimal)field.val()); }`

Ở đây, chúng ta sử dụng hàm `val` để chuyển đổi giá trị của từng trường StringField và sau đó tính tổng.

###### 3. Phức tạp: Kết hợp với LINQ để lọc và tính tổng:

`decimal totalAmount = nodeList.OfType () .Where(x => x.SelectSingleNode("MA_NHOM").val().ToString() == "1") .Sum(x => decimal.Parse(x.SelectSingleNode("THANH_TIEN").val().ToString()));`

Ở đây, chúng ta chỉ tính tổng các nút có `MA_NHOM` là 1 và sử dụng hàm `val` để lấy giá trị thực sự.

#### Hàm StringInStr

##### Công dụng:

Hàm StringInStr được sử dụng để kiểm tra xem một chuỗi có chứa chuỗi con cụ thể hay không.

##### Cấu trúc hàm:

`public static bool StringInStr(this object content, string val)`

##### Tham số:

- content: Đối tượng chứa chuỗi cần kiểm tra.
- val: Chuỗi con cần kiểm tra.

##### Kết quả trả về:

Một giá trị boolean, `true` nếu chuỗi `content` chứa chuỗi `val`, `false` nếu không.

##### Ví dụ:

###### 1. Cơ bản: Kiểm tra chuỗi "Hello" có chứa chuỗi "ell" hay không:

`bool result = "Hello".StringInStr("ell");`

Giá trị của `result` sẽ là `true`.

###### 2. Kết hợp: Sử dụng trong điều kiện:

`if ("Hello World".StringInStr("World")) { // Thực hiện thao tác }`

Ở đây, chúng ta chỉ thực hiện thao tác nếu chuỗi `Hello World` chứa chuỗi `World`.

###### 3. Phức tạp: Kết hợp với LINQ:

`var filteredList = stringList.Where(s => s.StringInStr("filter")).ToList();`

Ở đây, chúng ta sử dụng LINQ để lọc ra các chuỗi chứa từ "filter" từ danh sách `stringList`.

#### Hàm StringExist

##### Công dụng:

Hàm này dùng để kiểm tra sự tồn tại của chuỗi con trong chuỗi đầu vào, với khả năng phức tạp về điều kiện và logic.

##### Cấu trúc hàm:

`public static bool StringExist(string selfVal, string val, string val2 = "")`

##### Tham số:

- selfVal: Chuỗi đầu vào cần kiểm tra.
- val: Chuỗi chứa các chuỗi con và điều kiện logic.
- val2: Chuỗi đầu vào thứ hai, không bắt buộc.

##### Kết quả trả về:

Một giá trị boolean, `true` nếu chuỗi `selfVal` hoặc `val2` chứa các chuỗi con trong `val` theo điều kiện logic, `false` nếu không.

##### Ví dụ:

###### 1. Cơ bản:

`bool result = StringExist("Hello", "He, lo");`

Giá trị của `result` sẽ là `true`.

###### 2. Kết hợp:

`if (StringExist("Hello World", "Hello; World")) { // Thực hiện thao tác }`

Ở đây, chúng ta chỉ thực hiện thao tác nếu chuỗi `Hello World` chứa chuỗi `Hello` hoặc `World`.

###### 3. Phức tạp:

`bool result = StringExist("Hello World", "Hello, World", "World Hello");`

Ở đây, chúng ta kiểm tra sự tồn tại của `Hello` và `World` trong cả hai chuỗi `Hello World` và `World Hello`.

#### Hàm StringReplace

##### Công dụng:

Hàm này dùng để thay thế một chuỗi cụ thể trong chuỗi gốc, với số lượng thay thế tối đa được quy định.

##### Cấu trúc hàm:

`public static string StringReplace(this string str, string oldValue, string newValue, int count)`

##### Tham số:

- str: Chuỗi đầu vào cần thay thế.
- oldValue: Chuỗi cần thay thế.
- newValue: Chuỗi thay thế.
- count: Số lượng lần thay thế tối đa.

##### Kết quả trả về:

Chuỗi sau khi đã thay thế.

##### Ví dụ:

###### 1. Cơ bản:

`string result = "Hello Hello".StringReplace("Hello", "Hi", 1);`

Giá trị của `result` sẽ là "Hi Hello".

###### 2. Kết hợp:

`if ("Hello Hello".StringReplace("Hello", "Hi", 2).Contains("Hi")) { // Thực hiện thao tác }`

Ở đây, chúng ta thay thế tất cả các chuỗi "Hello" bằng "Hi" và kiểm tra sự tồn tại của chuỗi "Hi".

###### 3. Phức tạp:

`string result = "Hello Hello Hello".StringReplace("Hello", "Hi", 2).StringReplace("Hi", "Hey", 1);`

Ở đây, chúng ta thay thế 2 lần "Hello" bằng "Hi", sau đó thay thế 1 lần "Hi" bằng "Hey". Chuỗi kết quả sẽ là "Hey Hi Hello".

#### Hàm Execute

##### Công dụng:

Hàm này dùng để thực thi đoạn mã C# động và trả về kết quả thực thi.

##### Cấu trúc hàm:

`public static object? Execute(string code)`

##### Tham số:

- code: Đoạn mã C# cần thực thi.

##### Kết quả trả về:

Kết quả của đoạn mã C# được thực thi, hoặc `null` nếu có lỗi.

##### Ví dụ:

###### 1. Cơ bản:

`var result = Execute("1 + 1");`

Giá trị của `result` sẽ là 2.

###### 2. Kết hợp:

`if ((bool)Execute("1 > 0")) { // Thực hiện thao tác }`

Ở đây, chúng ta thực thi đoạn mã "1 > 0" và sử dụng kết quả để điều kiện trong câu lệnh `if`.

###### 3. Phức tạp:

`var result = Execute("new List {1, 2, 3}.Sum()");`

Ở đây, chúng ta thực thi đoạn mã tạo mới một danh sách và tính tổng các phần tử. Kết quả sẽ là 6.

#### Hàm min

##### Công dụng:

Hàm này dùng để lấy phút từ một đối tượng thời gian.

##### Cấu trúc hàm:

`public static int min(this object selfVal)`

##### Tham số:

- selfVal: Đối tượng cần lấy phút.

##### Kết quả trả về:

Số phút trong đối tượng thời gian, hoặc `0` nếu có lỗi.

##### Ví dụ:

###### 1. Cơ bản:

`var result = min("2023-12-31 23:59:59");`

Giá trị của `result` sẽ là 59.

###### 2. Kết hợp:

`if (min("2023-12-31 23:59:59") > 30) { // Thực hiện thao tác }`

Ở đây, chúng ta sử dụng kết quả từ hàm `min` để làm điều kiện trong câu lệnh `if`.

###### 3. Phức tạp:

`var list = new List { "2023-12-31 23:59:59", "2023-12-31 23:30:59" }; var minValues = list.Select(x => min(x)).ToList();`

Ở đây, chúng ta có một danh sách các chuỗi thời gian và chúng ta sử dụng hàm `min` để lấy số phút từ mỗi chuỗi.

#### Hàm hour

##### Công dụng:

Hàm này dùng để lấy giờ từ một đối tượng thời gian.

##### Cấu trúc hàm:

`public static int hour(this object selfVal)`

##### Tham số:

- selfVal: Đối tượng cần lấy giờ.

##### Kết quả trả về:

Số giờ trong đối tượng thời gian, hoặc `0` nếu có lỗi.

##### Ví dụ:

###### 1. Cơ bản:

`var result = hour("2023-12-31 23:59:59");`

Giá trị của `result` sẽ là 23.

###### 2. Kết hợp:

`if (hour("2023-12-31 23:59:59") >= 12) { // Thực hiện thao tác }`

Ở đây, chúng ta sử dụng kết quả từ hàm `hour` để làm điều kiện trong câu lệnh `if`.

###### 3. Phức tạp:

`var list = new List { "2023-12-31 23:59:59", "2023-12-31 10:30:59" }; var hourValues = list.Select(x => hour(x)).ToList();`

Ở đây, chúng ta có một danh sách các chuỗi thời gian và chúng ta sử dụng hàm `hour` để lấy số giờ từ mỗi chuỗi.

#### Hàm day

##### Công dụng:

Hàm này dùng để lấy ngày từ một đối tượng thời gian.

##### Cấu trúc hàm:

`public static int day(this object selfVal)`

##### Tham số:

- selfVal: Đối tượng cần lấy ngày.

##### Kết quả trả về:

Số ngày trong đối tượng thời gian, hoặc `0` nếu có lỗi.

##### Ví dụ:

###### 1. Cơ bản:

`var result = day("2023-12-31");`

Giá trị của `result` sẽ là 31.

###### 2. Kết hợp:

`if (day("2023-12-31") == 31) { // Thực hiện thao tác }`

Ở đây, chúng ta sử dụng kết quả từ hàm `day` để làm điều kiện trong câu lệnh `if`.

###### 3. Phức tạp:

`var list = new List { "2023-12-31", "2023-12-30", "2023-12-29" }; var dayValues = list.Select(x => day(x)).ToList();`

Ở đây, chúng ta có một danh sách các chuỗi thời gian và chúng ta sử dụng hàm `day` để lấy số ngày từ mỗi chuỗi.

#### Hàm mon

##### Công dụng:

Hàm này dùng để lấy tháng từ một đối tượng thời gian.

##### Cấu trúc hàm:

`public static int mon(this object selfVal)`

##### Tham số:

- selfVal: Đối tượng cần lấy tháng.

##### Kết quả trả về:

Số tháng trong đối tượng thời gian, hoặc `0` nếu có lỗi.

##### Ví dụ:

###### 1. Cơ bản:

`var result = mon("2023-12-31");`

Giá trị của `result` sẽ là 12.

###### 2. Kết hợp:

`if (mon("2023-12-31") == 12) { // Thực hiện thao tác }`

Ở đây, chúng ta sử dụng kết quả từ hàm `mon` để làm điều kiện trong câu lệnh `if`.

###### 3. Phức tạp:

`var list = new List { "2023-12-31", "2023-11-30", "2023-10-29" }; var monthValues = list.Select(x => mon(x)).ToList();`

Ở đây, chúng ta có một danh sách các chuỗi thời gian và chúng ta sử dụng hàm `mon` để lấy số tháng từ mỗi chuỗi.

#### Hàm quater

##### Công dụng:

Hàm này dùng để lấy quý từ một đối tượng thời gian.

##### Cấu trúc hàm:

`public static int quater(this object selfVal)`

##### Tham số:

- selfVal: Đối tượng cần lấy quý.

##### Kết quả trả về:

Số quý trong đối tượng thời gian, hoặc `0` nếu có lỗi.

##### Ví dụ:

###### 1. Cơ bản:

`var result = quater("2023-04-15");`

Giá trị của `result` sẽ là 2.

###### 2. Kết hợp:

`if (quater("2023-04-15") == 2) { // Thực hiện thao tác }`

Ở đây, chúng ta sử dụng kết quả từ hàm `quater` để làm điều kiện trong câu lệnh `if`.

###### 3. Phức tạp:

`var list = new List { "2023-01-01", "2023-04-15", "2023-08-20" }; var quaterValues = list.Select(x => quater(x)).ToList();`

Ở đây, chúng ta có một danh sách các chuỗi thời gian và chúng ta sử dụng hàm `quater` để lấy số quý từ mỗi chuỗi.

#### Hàm quater

##### Công dụng:

Hàm này dùng để lấy quý từ một đối tượng thời gian.

##### Cấu trúc hàm:

`public static int quater(this object selfVal)`

##### Tham số:

- selfVal: Đối tượng cần lấy quý.

##### Kết quả trả về:

Số quý trong đối tượng thời gian, hoặc `0` nếu có lỗi.

##### Ví dụ:

###### 1. Cơ bản:

`var result = quater("2023-04-15");`

Giá trị của `result` sẽ là 2.

###### 2. Kết hợp:

`if (quater("2023-04-15") == 2) { // Thực hiện thao tác }`

Ở đây, chúng ta sử dụng kết quả từ hàm `quater` để làm điều kiện trong câu lệnh `if`.

###### 3. Phức tạp:

`var list = new List { "2023-01-01", "2023-04-15", "2023-08-20" }; var quaterValues = list.Select(x => quater(x)).ToList();`

Ở đây, chúng ta có một danh sách các chuỗi thời gian và chúng ta sử dụng hàm `quater` để lấy số quý từ mỗi chuỗi.

#### Hàm year

##### Công dụng:

Hàm này dùng để lấy năm từ một đối tượng thời gian.

##### Cấu trúc hàm:

`public static int year(this object selfVal)`

##### Tham số:

- selfVal: Đối tượng cần lấy năm.

##### Kết quả trả về:

Năm trong đối tượng thời gian, hoặc `0` nếu có lỗi.

##### Ví dụ:

###### 1. Cơ bản:

`var result = year("2023-04-15");`

Giá trị của `result` sẽ là 2023.

###### 2. Kết hợp:

`if (year("2023-04-15") == 2023) { // Thực hiện thao tác }`

Ở đây, chúng ta sử dụng kết quả từ hàm `year` để làm điều kiện trong câu lệnh `if`.

###### 3. Phức tạp:

`var list = new List { "2021-01-01", "2022-04-15", "2023-08-20" }; var yearValues = list.Select(x => year(x)).ToList();`

Ở đây, chúng ta có một danh sách các chuỗi thời gian và chúng ta sử dụng hàm `year` để lấy số năm từ mỗi chuỗi.

#### Hàm diff

##### Công dụng:

Hàm này dùng để tính sự khác biệt về thời gian giữa hai đối tượng thời gian.

##### Cấu trúc hàm:

`public static int diff(this object selfVal, object val, string Type = "D")`

##### Tham số:

- selfVal: Đối tượng thời gian đầu tiên.
- val: Đối tượng thời gian thứ hai.
- Type: Loại đơn vị thời gian cần tính (mặc định là "D" cho ngày).

##### Kết quả trả về:

Khác biệt thời gian giữa `selfVal` và `val` theo đơn vị `Type`, hoặc `0` nếu có lỗi.

##### Ví dụ:

###### 1. Cơ bản:

`var result = diff("2023-04-15", "2023-04-10");`

Giá trị của `result` sẽ là 5 ngày.

###### 2. Kết hợp:

`var days = diff("2023-04-15", "2023-04-10"); var hours = days * 24;`

Ở đây, chúng ta sử dụng kết quả từ hàm `diff` để tính số giờ.

###### 3. Phức tạp:

`var list1 = new List { "2023-04-15", "2023-05-15", "2023-06-15" }; var list2 = new List { "2023-04-10", "2023-05-10", "2023-06-10" }; var diffValues = list1.Zip(list2, (d1, d2) => diff(d1, d2)).ToList();`

Ở đây, chúng ta có hai danh sách các chuỗi thời gian và chúng ta sử dụng hàm `diff` để lấy khác biệt thời gian từ mỗi cặp chuỗi.

#### Hàm between

##### Công dụng:

Hàm này dùng để kiểm tra xem một đối tượng thời gian có nằm trong khoảng thời gian giữa hai đối tượng thời gian khác hay không.

##### Cấu trúc hàm:

`public static bool between(this object selfVal, object val1, object val2, string Type = "D")`

##### Tham số:

- selfVal: Đối tượng thời gian cần kiểm tra.
- val1: Đối tượng thời gian đầu tiên của khoảng thời gian.
- val2: Đối tượng thời gian thứ hai của khoảng thời gian.
- Type: Loại đơn vị thời gian cần kiểm tra (mặc định là "D" cho ngày).

##### Kết quả trả về:

Trả về `true` nếu `selfVal` nằm trong khoảng thời gian giữa `val1` và `val2`, ngược lại trả về `false`.

##### Ví dụ:

###### 1. Cơ bản:

`var result = between("2023-04-15", "2023-04-10", "2023-04-20");`

Giá trị của `result` sẽ là `true`.

###### 2. Kết hợp:

`var isBetween = between("2023-04-15", "2023-04-10", "2023-04-20"); if (isBetween) { // Thực hiện các hoạt động khác }`

Ở đây, chúng ta sử dụng kết quả từ hàm `between` để điều kiện cho các hoạt động khác.

###### 3. Phức tạp:

`var dates = new List { "2023-04-15", "2023-05-15", "2023-06-15" }; var results = dates.Select(d => between(d, "2023-04-10", "2023-06-20")).ToList();`

Ở đây, chúng ta có một danh sách các chuỗi thời gian và chúng ta sử dụng hàm `between` để kiểm tra từng chuỗi xem có nằm trong khoảng thời gian định trước hay không.

#### Hàm ToDateTime

##### Công dụng:

Hàm này dùng để chuyển đổi đối tượng thành chuỗi thời gian theo định dạng cụ thể.

##### Cấu trúc hàm:

`public static string ToDateTime(this object selfVal)`

##### Tham số:

- selfVal: Đối tượng cần chuyển đổi.

##### Kết quả trả về:

Trả về chuỗi thời gian theo định dạng cụ thể.

##### Ví dụ:

###### 1. Cơ bản:

`var result = ToDateTime("2023-04-15");`

Giá trị của `result` có thể là "15/04/2023" hoặc theo định dạng khác tùy vào hàm `Formater()`.

###### 2. Kết hợp:

`var dateString = ToDateTime("2023-04-15"); if (dateString == "15/04/2023") { // Thực hiện các hoạt động khác }`

Ở đây, chúng ta sử dụng kết quả từ hàm `ToDateTime` để điều kiện cho các hoạt động khác.

###### 3. Phức tạp:

`var dates = new List <object> { "2023-04-15", DateTime.Now, "2023-05-15" }; var formattedDates = dates.Select(d => ToDateTime(d)).ToList();`

Ở đây, chúng ta có một danh sách các đối tượng thời gian và chúng ta sử dụng hàm `ToDateTime` để chuyển đổi từng đối tượng thành chuỗi theo định dạng cụ thể.

#### Hàm Sum

##### Công dụng:

Hàm này dùng để tính tổng các giá trị của trường cụ thể trong danh sách đối tượng.

##### Cấu trúc hàm:

`public static decimal Sum<T>(this List<T> list, string field)`

##### Tham số:

- list: Danh sách các đối tượng cần tính tổng.
- field: Tên của trường cần tính tổng.

##### Kết quả trả về:

Trả về tổng các giá trị của trường cụ thể trong danh sách đối tượng dưới dạng số thập phân.

##### Ví dụ:

###### 1. Cơ bản:

`var list = new List<Product> { new Product { Price = 10 }, new Product { Price = 20 } }; var total = list.Sum("Price");`

Giá trị của `total` sẽ là 30.

###### 2. Kết hợp:

`var list = new List<Product> { new Product { Price = 10, Quantity = 2 }, new Product { Price = 20, Quantity = 1 } }; var total = list.Sum("Price"); var totalQuantity = list.Sum("Quantity");`

Ở đây, chúng ta tính tổng giá và tổng số lượng trong danh sách đối tượng.

###### 3. Phức tạp:

`var list = new List<Order> { new Order { Products = new List<Product> { new Product { Price = 10 }, new Product { Price = 20 } } }, new Order { Products = new List<Product> { new Product { Price = 30 } } } }; var total = list.SelectMany(o => o.Products).Sum("Price");`

Ở đây, chúng ta có một danh sách các đơn đặt hàng, mỗi đơn có một danh sách sản phẩm. Chúng ta sử dụng `SelectMany` để làm phẳng danh sách và sau đó tính tổng giá của tất cả sản phẩm.

#### Hàm SumIf

##### Công dụng:

Hàm này dùng để tính tổng các giá trị của trường cụ thể trong danh sách đối tượng, với điều kiện cụ thể.

##### Cấu trúc hàm:

`public static decimal SumIf<T>(this List<T> list, string field, string conditionExp)`

##### Tham số:

- list: Danh sách các đối tượng.
- field: Tên của trường cần tính tổng.
- conditionExp: Biểu thức điều kiện.

##### Kết quả trả về:

Trả về tổng các giá trị của trường cụ thể trong danh sách đối tượng nếu đáp ứng điều kiện, dưới dạng số thập phân.

##### Ví dụ:

###### 1. Cơ bản:

`var list = new List<Product> { new Product { Price = 10, Category = "Electronics" }, new Product { Price = 20, Category = "Clothing" } }; var total = list.SumIf("Price", "Category == 'Electronics'");`

Giá trị của `total` sẽ là 10.

###### 2. Kết hợp:

`var list = new List<Product> { new Product { Price = 10, Category = "Electronics", Quantity = 2 }, new Product { Price = 20, Category = "Clothing", Quantity = 1 } }; var total = list.SumIf("Price", "Quantity > 1");`

Ở đây, chúng ta tính tổng giá của các sản phẩm có số lượng lớn hơn 1.

###### 3. Phức tạp:

`var list = new List<Order> { new Order { Products = new List<Product> { new Product { Price = 10, Category = "Electronics" }, new Product { Price = 20, Category = "Clothing" } } }, new Order { Products = new List<Product> { new Product { Price = 30, Category = "Electronics" } } } }; var total = list.SelectMany(o => o.Products).SumIf("Price", "Category == 'Electronics'");`

Ở đây, chúng ta có một danh sách các đơn đặt hàng, mỗi đơn có một danh sách sản phẩm. Chúng ta sử dụng `SelectMany` để làm phẳng danh sách và sau đó tính tổng giá của các sản phẩm thuộc danh mục 'Electronics'.

#### Hàm CountIf

##### Công dụng:

Hàm này dùng để đếm số lượng các đối tượng trong danh sách thỏa mãn điều kiện cụ thể.

##### Cấu trúc hàm:

`public static int CountIf<T>(this List<T> list, string ConditionExp)`

##### Tham số:

- list: Danh sách các đối tượng.
- ConditionExp: Biểu thức điều kiện.

##### Kết quả trả về:

Trả về số lượng các đối tượng trong danh sách thỏa mãn điều kiện, dưới dạng số nguyên.

##### Ví dụ:

###### 1. Cơ bản:

`var list = new List<Product> { new Product { Price = 10, Category = "Electronics" }, new Product { Price = 20, Category = "Clothing" } }; var count = list.CountIf("Category == 'Electronics'");`

Giá trị của `count` sẽ là 1.

###### 2. Kết hợp:

`var list = new List<Product> { new Product { Price = 10, Category = "Electronics", Quantity = 2 }, new Product { Price = 20, Category = "Clothing", Quantity = 1 } }; var count = list.CountIf("Quantity > 1");`

Ở đây, chúng ta đếm số lượng các sản phẩm có số lượng lớn hơn 1. Giá trị của `count` sẽ là 1.

###### 3. Phức tạp:

`var list = new List<Order> { new Order { Products = new List<Product> { new Product { Price = 10, Category = "Electronics" }, new Product { Price = 20, Category = "Clothing" } } }, new Order { Products = new List<Product> { new Product { Price = 30, Category = "Electronics" } } } }; var count = list.SelectMany(o => o.Products).CountIf("Category == 'Electronics'");`

Ở đây, chúng ta có một danh sách các đơn đặt hàng, mỗi đơn có một danh sách sản phẩm. Chúng ta sử dụng `SelectMany` để làm phẳng danh sách và sau đó đếm số lượng sản phẩm thuộc danh mục 'Electronics'. Giá trị của `count` sẽ là 2.

#### Hàm VlookUp

##### Công dụng:

Hàm này dùng để tìm kiếm một giá trị trong danh sách đối tượng dựa trên một trường cụ thể và trả về giá trị của một trường khác trong cùng một đối tượng.

##### Cấu trúc hàm:

`public static T? VlookUp<T>(this List<T> list, object ValueLooUp, string FieldLooUp, string FieldReturn)`

##### Tham số:

- list: Danh sách các đối tượng.
- ValueLooUp: Giá trị cần tìm kiếm.
- FieldLooUp: Trường cần tìm kiếm.
- FieldReturn: Trường cần trả về.

##### Kết quả trả về:

Trả về giá trị của trường cần trả về trong đối tượng đầu tiên thỏa mãn điều kiện, hoặc `null` nếu không tìm thấy.

##### Ví dụ:

###### 1. Cơ bản:

`var list = new List<Product> { new Product { ID = 1, Name = "Laptop" }, new Product { ID = 2, Name = "Phone" } }; var result = list.VlookUp(1, "ID", "Name");`

Giá trị của `result` sẽ là "Laptop".

###### 2. Kết hợp:

`var list = new List<Order> { new Order { ID = 1, Products = new List<Product> { new Product { ID = 1, Name = "Laptop" } } }, new Order { ID = 2, Products = new List<Product> { new Product { ID = 2, Name = "Phone" } } } }; var result = list.SelectMany(o => o.Products).VlookUp(2, "ID", "Name");`

Ở đây, chúng ta có danh sách các đơn đặt hàng. Mỗi đơn có một danh sách sản phẩm. Chúng ta dùng `SelectMany` để làm phẳng danh sách, sau đó sử dụng `VlookUp` để tìm sản phẩm có ID là 2. Giá trị của `result` sẽ là "Phone".

###### 3. Phức tạp:

`var list = new List<Order> { new Order { ID = 1, Products = new List<Product> { new Product { ID = 1, Name = "Laptop", Price = 1000 }, new Product { ID = 2, Name = "Phone", Price = 500 } } }, new Order { ID = 2, Products = new List<Product> { new Product { ID = 3, Name = "TV", Price = 2000 } } } }; var result = list.SelectMany(o => o.Products).Where(p => p.Price > 600).VlookUp(3, "ID", "Name");`

Ở đây, chúng ta có danh sách các đơn đặt hàng với các sản phẩm có giá khác nhau. Chúng ta tìm các sản phẩm có giá lớn hơn 600 và sau đó sử dụng `VlookUp` để tìm sản phẩm có ID là 3. Giá trị của `result` sẽ là "TV".

#### Hàm TLookUp

##### Công dụng:

Hàm này dùng để lọc danh sách các đối tượng dựa trên một biểu thức điều kiện.

##### Cấu trúc hàm:

`public static List<T>? TLookUp<T>(this List<T> list, string conditionExp = "")`

##### Tham số:

- list: Danh sách các đối tượng.
- conditionExp: Biểu thức điều kiện để lọc.

##### Kết quả trả về:

Trả về danh sách các đối tượng thỏa mãn điều kiện, hoặc `null` nếu danh sách đầu vào là `null`.

##### Ví dụ:

###### 1. Cơ bản:

`var list = new List<Product> { new Product { ID = 1, Name = "Laptop" }, new Product { ID = 2, Name = "Phone" } }; var result = list.TLookUp("ID == 1");`

Giá trị của `result` sẽ là danh sách chỉ chứa sản phẩm có ID là 1.

###### 2. Kết hợp:

`var list = new List<Product> { new Product { ID = 1, Name = "Laptop" }, new Product { ID = 2, Name = "Phone" } }; var result = list.TLookUp("ID == 1").VlookUp(1, "ID", "Name");`

Ở đây, chúng ta kết hợp `TLookUp` với `VLookUp`. `result` sẽ là "Laptop".

###### 3. Phức tạp:

`var list = new List<Order> { new Order { ID = 1, Products = new List<Product> { new Product { ID = 1, Name = "Laptop", Price = 1000 }, new Product { ID = 2, Name = "Phone", Price = 500 } } }, new Order { ID = 2, Products = new List<Product> { new Product { ID = 3, Name = "TV", Price = 2000 } } } }; var result = list.SelectMany(o => o.Products).TLookUp("Price > 600").Sum("Price");`

Ở đây, chúng ta có danh sách các đơn đặt hàng với các sản phẩm có giá khác nhau. Chúng ta dùng `SelectMany` để làm phẳng danh sách, sau đó sử dụng `TLookUp` để lọc các sản phẩm có giá trên 600 và tính tổng giá của chúng. Giá trị của `result` sẽ là 3000.

#### Hàm IsPTTT

##### Công dụng:

Hàm này dùng để kiểm tra xem trong tài liệu XML có phải là Phẫu thuật/Thủ thuật hay không.

##### Cấu trúc hàm:

`public static bool IsPTTT(this XmlDocument hoso)`

##### Tham số:

- hoso: Tài liệu XML cần kiểm tra.

##### Kết quả trả về:

Trả về `true` nếu trong tài liệu XML có thông tin về Phẫu thuật/Thủ thuật, ngược lại trả về `false`.

##### Ví dụ:

###### 1. Cơ bản:

`XmlDocument hoso = new XmlDocument(); hoso.LoadXml("<root><CHI_TIET_DVKT MA_NHOM='8'/></root>"); bool result = hoso.IsPTTT();`

Ở ví dụ này, `result` sẽ trả về `true` vì có node `CHI_TIET_DVKT` có thuộc tính `MA_NHOM` là 8.

###### 2. Kết hợp:

`XmlDocument hoso = new XmlDocument(); hoso.LoadXml("<root><CHI_TIET_DVKT MA_NHOM='8'/></root>"); bool isPTTT = hoso.IsPTTT(); string message = isPTTT ? "Có Phẫu thuật/Thủ thuật" : "Không có Phẫu thuật/Thủ thuật";`

Ở đây, `isPTTT` sẽ trả về `true` và `message` sẽ là "Có Phẫu thuật/Thủ thuật".

###### 3. Phức tạp:

`XmlDocument hoso = new XmlDocument(); hoso.LoadXml("<root><CHI_TIET_DVKT MA_NHOM='8'/><CHI_TIET_DVKT MA_NHOM='18'/></root>"); bool isPTTT = hoso.IsPTTT(); string message = isPTTT ? "Có Phẫu thuật/Thủ thuật" : "Không có Phẫu thuật/Thủ thuật";`

Ở đây, `isPTTT` sẽ trả về `true` vì có hai node `CHI_TIET_DVKT` có thuộc tính `MA_NHOM` là 8 và 18. `message` sẽ là "Có Phẫu thuật/Thủ thuật".

#### Hàm IsPT IsTT

##### Công dụng:

Hàm này dùng để kiểm tra xem trong tài liệu XML có phải là Phẫu thuật/Thủ thuật hay không.

##### Cấu trúc hàm:

`public static bool IsPT(this XmlDocument hoso)`
`public static bool IsTT(this XmlDocument hoso)`

##### Tham số:

- hoso: Tài liệu XML cần kiểm tra.

##### Kết quả trả về:

Trả về `true` nếu trong tài liệu XML có thông tin về Phẫu thuật/Thủ thuật, ngược lại trả về `false`.

##### Ví dụ:

###### 1. Cơ bản:

`// Hàm IsPT XmlDocument hoso = new XmlDocument(); hoso.LoadXml(""); bool result = hoso.IsPT(); // Trả về true`

###### 2. Kết hợp:

`// Kết hợp hàm IsPT và IsTT XmlDocument hoso = new XmlDocument(); hoso.LoadXml(""); bool isPT = hoso.IsPT(); // true bool isTT = hoso.IsTT(); // true`

###### 3. Phức tạp:

`// Sử dụng hàm IsTruocPT và IsSauPT với XML130 XML130 hoso130 = new XML130(); // Giả sử đã có dữ liệu CHI_TIET_DVKT_130 item = new CHI_TIET_DVKT_130(); // Giả sử đã có dữ liệu bool truocPT = hoso130.IsTruocPT(item); // true hoặc false bool sauPT = hoso130.IsSauPT(item); // true hoặc false`

#### Hàm ToInt

##### Công dụng:

Hàm này dùng để chuyển đổi nội dung của một đối tượng XmlNode sang kiểu số nguyên (int).

##### Cấu trúc hàm:

`public static int ToInt(this XmlNode str)`

##### Tham số:

- str: Đối tượng XmlNode cần chuyển đổi.

##### Kết quả trả về:

Trả về một số nguyên có giá trị là nội dung của XmlNode đã được chuyển đổi.

##### Ví dụ:

###### 1. Cơ bản:

`XmlDocument doc = new XmlDocument(); doc.LoadXml("<root><item>123</item></root>"); XmlNode node = doc.SelectSingleNode("/root/item"); int result = node.ToInt();`

Ở ví dụ này, `result` sẽ trả về 123.

###### 2. Kết hợp:

`XmlDocument doc = new XmlDocument(); doc.LoadXml("<root><item1>123</item1><item2>456</item2></root>"); int sum = doc.SelectSingleNode("/root/item1").ToInt() + doc.SelectSingleNode("/root/item2").ToInt();`

Ở đây, `sum` sẽ trả về 579.

###### 3. Phức tạp:

`XmlDocument doc = new XmlDocument(); doc.LoadXml("<root><items><item>1</item><item>2</item><item>3</item></items></root>"); XmlNodeList nodes = doc.SelectNodes("/root/items/item"); int sum = 0; foreach (XmlNode node in nodes) { sum += node.ToInt(); }`

Ở ví dụ này, `sum` sẽ trả về 6 (1+2+3).

#### Hàm ToDecimal

##### Công dụng:

Hàm này dùng để chuyển đổi nội dung của một đối tượng XmlNode sang kiểu số thập phân (decimal).

##### Cấu trúc hàm:

`public static decimal ToDecimal(this XmlNode str)`

##### Tham số:

- str: Đối tượng XmlNode cần chuyển đổi.

##### Kết quả trả về:

Trả về một số thập phân có giá trị là nội dung của XmlNode đã được chuyển đổi.

##### Ví dụ:

###### 1. Cơ bản:

`XmlDocument doc = new XmlDocument(); doc.LoadXml("<root><item>123.45</item></root>"); XmlNode node = doc.SelectSingleNode("/root/item"); decimal result = node.ToDecimal();`

Ở ví dụ này, `result` sẽ trả về 123.45.

###### 2. Kết hợp:

`XmlDocument doc = new XmlDocument(); doc.LoadXml("<root><item1>123.45</item1><item2>678.9</item2></root>"); decimal sum = doc.SelectSingleNode("/root/item1").ToDecimal() + doc.SelectSingleNode("/root/item2").ToDecimal();`

Ở đây, `sum` sẽ trả về 802.35.

###### 3. Phức tạp:

`XmlDocument doc = new XmlDocument(); doc.LoadXml("<root><items><item>1.1</item><item>2.2</item><item>3.3</item></items></root>"); XmlNodeList nodes = doc.SelectNodes("/root/items/item"); decimal sum = 0; foreach (XmlNode node in nodes) { sum += node.ToDecimal(); }`

Ở ví dụ này, `sum` sẽ trả về 6.6 (1.1+2.2+3.3).

#### Hàm ToText

##### Công dụng:

Hàm này dùng để lấy nội dung dạng văn bản (text) từ một đối tượng XmlNode.

##### Cấu trúc hàm:

`public static string ToText(this XmlNode str)`

##### Tham số:

- str: Đối tượng XmlNode từ đó cần lấy nội dung văn bản.

##### Kết quả trả về:

Trả về một chuỗi chứa nội dung văn bản của XmlNode. Nếu XmlNode là null, trả về chuỗi rỗng.

##### Ví dụ:

###### 1. Cơ bản:

`XmlDocument doc = new XmlDocument(); doc.LoadXml("<root><item>Hello</item></root>"); XmlNode node = doc.SelectSingleNode("/root/item"); string result = node.ToText();`

Ở ví dụ này, `result` sẽ trả về "Hello".

###### 2. Kết hợp:

`XmlDocument doc = new XmlDocument(); doc.LoadXml("<root><item>Hello</item><item>World</item></root>"); XmlNodeList nodes = doc.SelectNodes("/root/item"); string combinedText = string.Join(" ", nodes.OfType<XmlNode>().Select(n => n.ToText()));`

Ở đây, `combinedText` sẽ trả về "Hello World".

###### 3. Phức tạp:

`XmlDocument doc = new XmlDocument(); doc.LoadXml("<root><items><item>Hello</item><item>World</item><item>!</item></items></root>"); string sentence = doc.SelectSingleNode("/root/items").ChildNodes.OfType<XmlNode>().Select(n => n.ToText()).Aggregate((a, b) => a + " " + b);`

Ở ví dụ này, `sentence` sẽ trả về "Hello World !".

#### Hàm DateLessThan

##### Công dụng:

Hàm này dùng để so sánh hai đối tượng ngày tháng và kiểm tra xem ngày tháng trong đối tượng đầu tiên có nhỏ hơn ngày tháng trong đối tượng thứ hai hay không.

##### Cấu trúc hàm:

`public static bool DateLessThan(this object obj, object obj1)`

##### Tham số:

- obj: Đối tượng đầu tiên có thể là kiểu DateTime hoặc chuỗi.
- obj1: Đối tượng thứ hai có thể là kiểu DateTime hoặc chuỗi.

##### Kết quả trả về:

Trả về `true` nếu ngày tháng của đối tượng đầu tiên nhỏ hơn ngày tháng của đối tượng thứ hai, ngược lại trả về `false`.

##### Ví dụ:

###### 1. Cơ bản:

`bool result = "2021-01-01".DateLessThan("2021-01-02");`

Ở ví dụ này, `result` sẽ trả về `true` vì "2021-01-01" nhỏ hơn "2021-01-02".

###### 2. Kết hợp:

`DateTime dt1 = new DateTime(2021, 1, 1); DateTime dt2 = new DateTime(2021, 1, 2); bool result = dt1.DateLessThan(dt2);`

Ở đây, `result` sẽ trả về `true` vì `dt1` nhỏ hơn `dt2`.

###### 3. Phức tạp:

`object obj1 = "2021-01-01"; object obj2 = new DateTime(2021, 1, 2); bool result = obj1.DateLessThan(obj2);`

Ở đây, `result` sẽ trả về `true` vì ngày trong `obj1` nhỏ hơn ngày trong `obj2`.

#### Hàm DateEqualLessThan

##### Công dụng:

Hàm này dùng để so sánh hai đối tượng ngày tháng và kiểm tra xem ngày tháng trong đối tượng đầu tiên có nhỏ hơn hoặc bằng ngày tháng trong đối tượng thứ hai hay không.

##### Cấu trúc hàm:

`public static bool DateEqualLessThan(this object obj, object obj1)`

##### Tham số:

- obj: Đối tượng đầu tiên có thể là kiểu DateTime hoặc chuỗi.
- obj1: Đối tượng thứ hai có thể là kiểu DateTime hoặc chuỗi.

##### Kết quả trả về:

Trả về `true` nếu ngày tháng của đối tượng đầu tiên nhỏ hơn hoặc bằng ngày tháng của đối tượng thứ hai, ngược lại trả về `false`.

##### Ví dụ:

###### 1. Cơ bản:

`bool result = "2021-01-01".DateEqualLessThan("2021-01-01");`

Ở ví dụ này, `result` sẽ trả về `true` vì "2021-01-01" bằng "2021-01-01".

###### 2. Kết hợp:

`DateTime dt1 = new DateTime(2021, 1, 1); DateTime dt2 = new DateTime(2021, 1, 2); bool result = dt1.DateEqualLessThan(dt2);`

Ở đây, `result` sẽ trả về `true` vì `dt1` nhỏ hơn `dt2`.

###### 3. Phức tạp:

`object obj1 = "2021-01-01"; object obj2 = new DateTime(2021, 1, 2); bool result = obj1.DateEqualLessThan(obj2);`

Ở đây, `result` sẽ trả về `true` vì ngày trong `obj1` nhỏ hơn ngày trong `obj2`.

#### Hàm DateEqualLessThan

##### Công dụng:

Hàm này dùng để so sánh hai đối tượng ngày tháng và kiểm tra xem ngày tháng trong đối tượng đầu tiên có nhỏ hơn hoặc bằng ngày tháng trong đối tượng thứ hai hay không.

##### Cấu trúc hàm:

`public static bool DateEqualLessThan(this object obj, object obj1)`

##### Tham số:

- obj: Đối tượng đầu tiên có thể là kiểu DateTime hoặc chuỗi.
- obj1: Đối tượng thứ hai có thể là kiểu DateTime hoặc chuỗi.

##### Kết quả trả về:

Trả về `true` nếu ngày tháng của đối tượng đầu tiên nhỏ hơn hoặc bằng ngày tháng của đối tượng thứ hai, ngược lại trả về `false`.

##### Ví dụ:

###### 1. Cơ bản:

`bool result = "2021-01-01".DateEqualLessThan("2021-01-01");`

Ở ví dụ này, `result` sẽ trả về `true` vì "2021-01-01" bằng "2021-01-01".

###### 2. Kết hợp:

`DateTime dt1 = new DateTime(2021, 1, 1); DateTime dt2 = new DateTime(2021, 1, 2); bool result = dt1.DateEqualLessThan(dt2);`

Ở đây, `result` sẽ trả về `true` vì `dt1` nhỏ hơn `dt2`.

###### 3. Phức tạp:

`object obj1 = "2021-01-01"; object obj2 = new DateTime(2021, 1, 2); bool result = obj1.DateEqualLessThan(obj2);`

Ở đây, `result` sẽ trả về `true` vì ngày trong `obj1` nhỏ hơn ngày trong `obj2`.

#### Hàm DateEqualGetterThan

##### Công dụng:

Hàm này dùng để so sánh hai đối tượng ngày tháng và kiểm tra xem ngày tháng trong đối tượng đầu tiên có lớn hơn hoặc bằng ngày tháng trong đối tượng thứ hai hay không.

##### Cấu trúc hàm:

`public static bool DateEqualGetterThan(this object obj, object obj1)`

##### Tham số:

- obj: Đối tượng đầu tiên có thể là kiểu DateTime hoặc chuỗi.
- obj1: Đối tượng thứ hai có thể là kiểu DateTime hoặc chuỗi.

##### Kết quả trả về:

Trả về `true` nếu ngày tháng của đối tượng đầu tiên lớn hơn hoặc bằng ngày tháng của đối tượng thứ hai, ngược lại trả về `false`.

##### Ví dụ:

###### 1. Cơ bản:

`bool result = "2021-01-01".DateEqualGetterThan("2021-01-01");`

Ở ví dụ này, `result` sẽ trả về `true` vì "2021-01-01" bằng "2021-01-01".

###### 2. Kết hợp:

`DateTime dt1 = new DateTime(2021, 1, 2); DateTime dt2 = new DateTime(2021, 1, 1); bool result = dt1.DateEqualGetterThan(dt2);`

Ở đây, `result` sẽ trả về `true` vì `dt1` lớn hơn `dt2`.

###### 3. Phức tạp:

`object obj1 = "2021-01-02"; object obj2 = new DateTime(2021, 1, 1); bool result = obj1.DateEqualGetterThan(obj2);`

Ở đây, `result` sẽ trả về `true` vì ngày trong `obj1` lớn hơn ngày trong `obj2`.

#### Hàm DateEqual

##### Công dụng:

Hàm này dùng để so sánh hai đối tượng ngày tháng và kiểm tra xem ngày tháng trong đối tượng đầu tiên có bằng ngày tháng trong đối tượng thứ hai hay không.

##### Cấu trúc hàm:

`public static bool DateEqual(this object obj, object obj1)`

##### Tham số:

- obj: Đối tượng đầu tiên có thể là kiểu DateTime hoặc chuỗi.
- obj1: Đối tượng thứ hai có thể là kiểu DateTime hoặc chuỗi.

##### Kết quả trả về:

Trả về `true` nếu ngày tháng của đối tượng đầu tiên bằng ngày tháng của đối tượng thứ hai, ngược lại trả về `false`.

##### Ví dụ:

###### 1. Cơ bản:

`bool result = "2021-01-01".DateEqual("2021-01-01");`

Ở ví dụ này, `result` sẽ trả về `true` vì "2021-01-01" bằng "2021-01-01".

###### 2. Kết hợp:

`DateTime dt1 = new DateTime(2021, 1, 1); DateTime dt2 = new DateTime(2021, 1, 1); bool result = dt1.DateEqual(dt2);`

Ở đây, `result` sẽ trả về `true` vì `dt1` bằng `dt2`.

###### 3. Phức tạp:

`object obj1 = "2021-01-01"; object obj2 = new DateTime(2021, 1, 1); bool result = obj1.DateEqual(obj2);`

Ở đây, `result` sẽ trả về `true` vì ngày trong `obj1` bằng ngày trong `obj2`.

#### Hàm DateDiff

##### Công dụng:

Hàm này dùng để tính toán sự khác biệt về thời gian giữa hai đối tượng ngày.

##### Cấu trúc hàm:

`public static int? DateDiff(this object obj, object obj1, string type = "D")`

##### Tham số:

- obj: Đối tượng ngày tháng đầu tiên.
- obj1: Đối tượng ngày tháng thứ hai.
- type: Loại đơn vị thời gian để tính sự khác biệt. Mặc định là "D" (ngày).

##### Kết quả trả về:

Trả về sự khác biệt về thời gian giữa hai đối tượng ngày dựa trên đơn vị thời gian đã chọn. Nếu một trong hai đối tượng ngày là null, hàm sẽ trả về null.

##### Ví dụ:

###### 1. Cơ bản:

`int? result = "2021-01-01".DateDiff("2021-01-02");`

Ở ví dụ này, `result` sẽ trả về -1 vì có 1 ngày chênh lệch và đối số thứ hai lớn hơn đối số đầu tiên.

###### 2. Kết hợp:

`DateTime dt1 = new DateTime(2021, 1, 1); DateTime dt2 = new DateTime(2021, 1, 10); int? result = dt1.DateDiff(dt2, "D");`

Ở đây, `result` sẽ trả về -9, bởi vì có 9 ngày chênh lệch và `dt2` lớn hơn `dt1`.

###### 3. Phức tạp:

`DateTime dt1 = new DateTime(2021, 1, 1, 10, 0, 0); DateTime dt2 = new DateTime(2021, 1, 1, 11, 0, 0); int? result = dt1.DateDiff(dt2, "h");`

Ở đây, `result` sẽ trả về -1, bởi vì có 1 giờ chênh lệch và đơn vị thời gian là giờ (`"h"`).

#### Hàm Red

##### Công dụng:

Hàm này dùng để định dạng một đối tượng với màu đỏ trong HTML.

##### Cấu trúc hàm:

`public static string Red(this object obj)`
`public static string Blue(this object obj)`
`public static string Purple(this object obj)`
`public static string Orange(this object obj)`
`public static string Grey(this object obj)`

##### Tham số:

- obj: Đối tượng cần định dạng.

##### Kết quả trả về:

Trả về chuỗi HTML định dạng đối tượng với màu đỏ.

##### Ví dụ:

###### 1. Cơ bản:

`string result = "Hello".Red();`

Ở ví dụ này, `result` sẽ trả về chuỗi HTML `"<b style=\"color:red;\">Hello</b>"`, định dạng từ "Hello" với màu đỏ.

#### Hàm JoinList

##### Công dụng:

Hàm này dùng để nối các phần tử của một danh sách thành một chuỗi, cách nhau bởi một dấu phân cách.

##### Cấu trúc hàm:

`public static string JoinList<T>(this IEnumerable<T> list, string delimiter)`

##### Tham số:

- list: Danh sách các phần tử cần nối.
- delimiter: Dấu phân cách giữa các phần tử khi nối.

##### Kết quả trả về:

Trả về một chuỗi nối tất cả các phần tử của danh sách, cách nhau bởi dấu phân cách.

##### Ví dụ:

###### 1. Cơ bản:

`var list = new List<int> { 1, 2, 3 }; string result = list.JoinList(",");`

Ở ví dụ này, `result` sẽ trả về chuỗi "1,2,3".

###### 2. Kết hợp:

`var list = new List<string> { "apple", "orange", "banana" }; string result = list.JoinList(" and ");`

Ở ví dụ này, `result` sẽ trả về chuỗi "apple and orange and banana".

###### 3. Phức tạp:

`var list = new List<List<int>> { new List<int> {1, 2}, new List<int> {3, 4} }; string result = list.Select(subList => subList.JoinList("+")).JoinList(" , ");`

Ở ví dụ này, `result` sẽ trả về chuỗi "1+2 , 3+4" vì nó sẽ nối từng danh sách con trước.

#### Hàm JoinCols

##### Công dụng:

Hàm này dùng để nối giá trị của một cột trong danh sách các đối tượng, sử dụng tên của thuộc tính lồng nhau.

##### Cấu trúc hàm:

`public static string JoinCols<T>(this IEnumerable<T> list, string ColumnName, string NestedProperty = "Value")`

##### Tham số:

- list: Danh sách các đối tượng cần nối.
- ColumnName: Tên của cột cần nối.
- NestedProperty: Tên của thuộc tính lồng nhau (mặc định là "Value").

##### Kết quả trả về:

Trả về một chuỗi nối tất cả các giá trị của cột được chỉ định trong danh sách, cách nhau bởi dấu phân cách.

##### Ví dụ:

###### 1. Cơ bản:

`var list = new List<Person> { new Person { Age = new NestedValue { Value = "30" } }, new Person { Age = new NestedValue { Value = "40" } } }; string result = list.JoinCols("Age");`

Ở ví dụ này, `result` sẽ trả về chuỗi "30, 40".

###### 2. Kết hợp:

`var list = new List<Person> { new Person { Age = new NestedValue { Value = "30", Unit = "Years" } }, new Person { Age = new NestedValue { Value = "40", Unit = "Years" } } }; string result = list.JoinCols("Age", "Unit");`

Ở ví dụ này, `result` sẽ trả về chuỗi "Years, Years".

###### 3. Phức tạp:

`var list = new List<Person> { new Person { Age = new NestedValue { Value = "30", Unit = "Years" } }, new Person { Age = null }, new Person { Age = new NestedValue { Value = "50", Unit = "Years" } } }; string result = list.JoinCols("Age");`

Ở ví dụ này, `result` sẽ trả về chuỗi "30, , 50" vì một đối tượng có giá trị null cho thuộc tính "Age".

#### Các phép so sánh logic trong C#

##### Giới thiệu:

Trong C#, các phép so sánh logic dùng để kết hợp nhiều điều kiện.

##### Danh sách các phép so sánh:

- && (AND): Trả về true nếu cả hai điều kiện là true.
- || (OR): Trả về true nếu ít nhất một trong hai điều kiện là true.
- ! (NOT): Đảo ngược giá trị của điều kiện.

##### Ví dụ:

###### 1. Cơ bản:

`bool isTrue = true; bool isFalse = false; bool result = isTrue && isFalse; // result will be false`

Ở ví dụ này, `result` sẽ trả về false vì một trong hai điều kiện là false.

###### 2. Trung bình:

`int x = 5; int y = 10; bool result = (x < y) || (x == y); // result will be true`

Ở ví dụ này, `result` sẽ trả về true vì ít nhất một trong hai điều kiện là true.

###### 3. Phức tạp:

`int x = 5; int y = 10; int z = 15; bool result = (x < y) && ((y < z) || (x == z)); // result will be true`

Ở ví dụ này, `result` sẽ trả về true vì tất cả các điều kiện phức tạp đều đúng.

#### Các hàm hay được sử dụng trong LINQ trong C#

##### Giới thiệu:

Language Integrated Query (LINQ) là một tính năng trong C# dùng để thực hiện các truy vấn dữ liệu.

##### Danh sách các hàm hay sử dụng:

- Where: Lọc các phần tử trong một collection dựa trên điều kiện.
- Select: Chọn các phần tử hoặc thuộc tính cụ thể từ một collection.
- OrderBy/OrderByDescending: Sắp xếp các phần tử trong một collection.
- Count: Đếm số lượng phần tử trong một collection.
- First/FirstOrDefault: Lấy phần tử đầu tiên trong một collection.
- Sum: Tính tổng của các phần tử trong một collection.

##### Ví dụ:

###### 1. Cơ bản:

`var numbers = new int[] { 1, 2, 3, 4, 5 }; var evenNumbers = numbers.Where(x => x % 2 == 0);`

Ở ví dụ này, `evenNumbers` sẽ chứa các số chẵn từ mảng `numbers`.

###### 2. Trung bình:

`var people = new List<Person> { new Person { Name = "John", Age = 30 }, new Person { Name = "Jane", Age = 25 } }; var names = people.Select(x => x.Name);`

Ở ví dụ này, `names` sẽ chứa các tên trong danh sách `people`.

###### 3. Phức tạp:

`var people = new List<Person> { new Person { Name = "John", Age = 30 }, new Person { Name = "Jane", Age = 25 } }; var oldestPerson = people.OrderByDescending(x => x.Age).FirstOrDefault();`

Ở ví dụ này, `oldestPerson` sẽ là người có tuổi cao nhất trong danh sách `people`.

#### Lớp HOSO130

##### Giới thiệu:

Lớp `HOSO130` là một cấu trúc dữ liệu trong C# được sử dụng để đại diện cho tài liệu XML 130.

##### Thuộc tính:

- XML1: Đối tượng của lớp `TONG_HOP_130`, chứa thông tin tổng hợp.
- XML2: Danh sách các đối tượng của lớp `CHI_TIET_THUOC_130`, chứa thông tin chi tiết về thuốc.
- XML3: Danh sách các đối tượng của lớp `CHI_TIET_DVKT_130`, chứa thông tin chi tiết về dịch vụ kỹ thuật.
- XML4: Danh sách các đối tượng của lớp `CHI_TIET_CLS_130`, chứa thông tin chi tiết về cận lâm sàng.
- XML5: Danh sách các đối tượng của lớp `CHI_TIET_DIEN_BIEN_BENH_130`, chứa thông tin chi tiết về diễn biến bệnh.

##### Ví dụ:

###### 1. Cơ bản:

`var hoso = new HOSO130(); hoso.XML1 = new TONG_HOP_130 { /* ... */ };`

Ở ví dụ này, chúng ta tạo ra một đối tượng `HOSO130` và khởi tạo thuộc tính `XML1`.

###### 2. Trung bình:

`var hoso = new HOSO130 { XML1 = new TONG_HOP_130 { /* ... */ }, XML2 = new List<CHI_TIET_THUOC_130> { /* ... */ } };`

Ở ví dụ này, chúng ta khởi tạo cả `XML1` và `XML2` trong cùng một đối tượng `HOSO130`.

###### 3. Phức tạp:

`var hoso = new HOSO130 { XML1 = new TONG_HOP_130 { /* ... */ }, XML2 = new List<CHI_TIET_THUOC_130> { /* ... */ }, XML3 = new List<CHI_TIET_DVKT_130> { /* ... */ }, XML4 = new List<CHI_TIET_CLS_130> { /* ... */ }, XML5 = new List<CHI_TIET_DIEN_BIEN_BENH_130> { /* ... */ } };`

Ở ví dụ này, chúng ta khởi tạo tất cả các thuộc tính của `HOSO130` để có một đối tượng đầy đủ.

#### Lớp TONG_HOP_130

##### Giới thiệu:

Lớp `TONG_HOP_130` mở rộng từ lớp `TONG_HOP` và được sử dụng để đại diện cho các thông tin tổng hợp trong tài liệu XML 130.

##### Thuộc tính:

- SO_CCCD: Chứng minh nhân dân
- MA_QUOCTICH: Mã quốc tịch
- MA_DANTOC: Mã dân tộc
- MA_NGHE_NGHIEP: Mã nghề nghiệp

##### Ví dụ:

###### 1. Cơ bản:

`var tonghop130 = new TONG_HOP_130(); tonghop130.SO_CCCD = new StringField() { Value = "123456789" }; tonghop130.MA_QUOCTICH = new IntField() { Value = 84 };`

Ở ví dụ này, chúng ta khởi tạo một đối tượng `TONG_HOP_130` và thiết lập các thuộc tính `SO_CCCD` và `MA_QUOCTICH`.

###### 2. Trung bình:

`var tonghop130 = new TONG_HOP_130() { SO_CCCD = new StringField() { Value = "123456789" }, MA_QUOCTICH = new IntField() { Value = 84 }, MA_DANTOC = new IntField() { Value = 1 } };`

Ở ví dụ này, chúng ta khởi tạo và thiết lập nhiều thuộc tính cùng một lúc.

###### 3. Phức tạp:

`var tonghop130 = new TONG_HOP_130("someBase64EncodedString");`

Ở ví dụ này, chúng ta khởi tạo `TONG_HOP_130` thông qua một chuỗi đã được mã hóa Base64, và lớp sẽ tự động giải mã và khởi tạo các thuộc tính dựa trên nội dung XML.

#### Lớp CHI_TIET_THUOC_130

##### Giới thiệu:

Lớp `CHI_TIET_THUOC_130` mở rộng từ lớp `CHI_TIET_THUOC` và được sử dụng để đại diện cho các thông tin chi tiết về thuốc trong tài liệu XML 130.

##### Thuộc tính:

- MA_PP_CHEBIEN: Mã phương pháp chế biến
- MA_CSKCB_THUOC: Mã cơ sở khám chữa bệnh cho thuốc
- DANG_BAO_CHE: Dạng bào chế
- CACH_DUNG: Cách dùng

##### Ví dụ:

###### 1. Cơ bản:

`var chitietthuoc130 = new CHI_TIET_THUOC_130(); chitietthuoc130.MA_PP_CHEBIEN = new StringField() { Value = "PP01" }; chitietthuoc130.MA_CSKCB_THUOC = new StringField() { Value = "CS01" };`

Ở ví dụ này, chúng ta khởi tạo một đối tượng `CHI_TIET_THUOC_130` và thiết lập các thuộc tính `MA_PP_CHEBIEN` và `MA_CSKCB_THUOC`.

###### 2. Trung bình:

`var chitietthuoc130 = new CHI_TIET_THUOC_130() { MA_PP_CHEBIEN = new StringField() { Value = "PP01" }, MA_CSKCB_THUOC = new StringField() { Value = "CS01" }, DANG_BAO_CHE = new StringField() { Value = "DBC01" } };`

Ở ví dụ này, chúng ta khởi tạo và thiết lập nhiều thuộc tính cùng một lúc.

###### 3. Phức tạp:

`var chitietthuoc130 = new CHI_TIET_THUOC_130(xmlNode);`

Ở ví dụ này, chúng ta khởi tạo `CHI_TIET_THUOC_130` thông qua một đối tượng `XmlNode`, và lớp sẽ tự động khởi tạo các thuộc tính dựa trên nội dung XML.

#### Lớp CHI_TIET_DVKT_130

##### Giới thiệu:

Lớp `CHI_TIET_DVKT_130` mở rộng từ lớp `CHI_TIET_DVKT` và được sử dụng để đại diện cho các thông tin chi tiết về dịch vụ kỹ thuật (DVKT) trong tài liệu XML 130.

##### Thuộc tính:

- MA_PTTT_QT: Mã phương pháp điều trị hoặc quy trình
- MA_XANG_DAU: Mã xăng dầu
- DON_GIA_BV: Đơn giá tại bệnh viện
- DON_GIA_BH: Đơn giá bảo hiểm

##### Ví dụ:

###### 1. Cơ bản:

`var chitietdvkt130 = new CHI_TIET_DVKT_130(); chitietdvkt130.MA_PTTT_QT = new StringField() { Value = "PT01" }; chitietdvkt130.MA_XANG_DAU = new StringField() { Value = "XD01" };`

Ở ví dụ này, chúng ta khởi tạo một đối tượng `CHI_TIET_DVKT_130` và thiết lập các thuộc tính `MA_PTTT_QT` và `MA_XANG_DAU`.

###### 2. Trung bình:

`var chitietdvkt130 = new CHI_TIET_DVKT_130() { MA_PTTT_QT = new StringField() { Value = "PT01" }, MA_XANG_DAU = new StringField() { Value = "XD01" }, DON_GIA_BV = new DecimalField() { Value = 1000.0m } };`

Ở ví dụ này, chúng ta khởi tạo và thiết lập nhiều thuộc tính cùng một lúc.

###### 3. Phức tạp:

`var chitietdvkt130 = new CHI_TIET_DVKT_130(xmlNode);`

Ở ví dụ này, chúng ta khởi tạo `CHI_TIET_DVKT_130` thông qua một đối tượng `XmlNode`, và lớp sẽ tự động khởi tạo các thuộc tính dựa trên nội dung XML.

#### Lớp CHI_TIET_CLS_130

##### Giới thiệu:

Lớp `CHI_TIET_CLS_130` mở rộng từ lớp `CHI_TIET_CLS` và được sử dụng để đại diện cho các thông tin chi tiết về cận lâm sàng trong tài liệu XML 130.

##### Thuộc tính:

- DON_VI_DO: Đơn vị đo của chỉ số
- MA_BS_DOC_KQ: Mã bác sĩ đọc kết quả
- DU_PHONG: Trường dự phòng

##### Ví dụ:

###### 1. Cơ bản:

`var chitietcls130 = new CHI_TIET_CLS_130(); chitietcls130.DON_VI_DO = new StringField() { Value = "mg" }; chitietcls130.MA_BS_DOC_KQ = new StringField() { Value = "BS01" };`

Ở ví dụ này, chúng ta khởi tạo một đối tượng `CHI_TIET_CLS_130` và thiết lập các thuộc tính `DON_VI_DO` và `MA_BS_DOC_KQ`.

###### 2. Trung bình:

`var chitietcls130 = new CHI_TIET_CLS_130() { DON_VI_DO = new StringField() { Value = "mg" }, MA_BS_DOC_KQ = new StringField() { Value = "BS01" }, DU_PHONG = new StringField() { Value = "Reserved" } };`

Ở ví dụ này, chúng ta khởi tạo và thiết lập nhiều thuộc tính cùng một lúc.

###### 3. Phức tạp:

`var chitietcls130 = new CHI_TIET_CLS_130(xmlNode);`

Ở ví dụ này, chúng ta khởi tạo `CHI_TIET_CLS_130` thông qua một đối tượng `XmlNode`, và lớp sẽ tự động khởi tạo các thuộc tính dựa trên nội dung XML.

#### Lớp CHI_TIET_DIEN_BIEN_BENH_130

##### Giới thiệu:

Lớp `CHI_TIET_DIEN_BIEN_BENH_130` mở rộng từ lớp `CHI_TIET_DIEN_BIEN_BENH` và được sử dụng để đại diện cho các thông tin chi tiết về diễn biến bệnh trong tài liệu XML 130.

##### Thuộc tính:

- DIEN_BIEN_LS: Lịch sử diễn biến bệnh
- GIAI_DOAN_BENH: Giai đoạn bệnh
- THOI_DIEM_DBLS: Thời điểm diễn biến lịch sử
- NGUOI_THUC_HIEN: Người thực hiện việc ghi nhận thông tin
- DU_PHONG: Trường dự phòng

##### Ví dụ:

###### 1. Cơ bản:

`var chitietdienbienbenh130 = new CHI_TIET_DIEN_BIEN_BENH_130(); chitietdienbienbenh130.DIEN_BIEN_LS = new StringField() { Value = "Stable" }; chitietdienbienbenh130.GIAI_DOAN_BENH = new StringField() { Value = "Initial" };`

Ở ví dụ này, chúng ta khởi tạo một đối tượng `CHI_TIET_DIEN_BIEN_BENH_130` và thiết lập các thuộc tính `DIEN_BIEN_LS` và `GIAI_DOAN_BENH`.

###### 2. Trung bình:

`var chitietdienbienbenh130 = new CHI_TIET_DIEN_BIEN_BENH_130() { DIEN_BIEN_LS = new StringField() { Value = "Stable" }, GIAI_DOAN_BENH = new StringField() { Value = "Initial" }, DU_PHONG = new StringField() { Value = "Reserved" } };`

Ở ví dụ này, chúng ta khởi tạo và thiết lập nhiều thuộc tính cùng một lúc.

###### 3. Phức tạp:

`var chitietdienbienbenh130 = new CHI_TIET_DIEN_BIEN_BENH_130(xmlNode);`

Ở ví dụ này, chúng ta khởi tạo `CHI_TIET_DIEN_BIEN_BENH_130` thông qua một đối tượng `XmlNode`, và lớp sẽ tự động khởi tạo các thuộc tính dựa trên nội dung XML.

#### Lớp XmlObject

##### Giới thiệu:

Lớp `XmlObject` là một lớp chứa được sử dụng để quản lý các đối tượng XML khác nhau, như HOSO4210 và HOSO130.

##### Thuộc tính:

- HOSO: Đối tượng XmlDocument chứa toàn bộ hồ sơ XML.
- XML4210: Đối tượng chứa các thông tin theo định dạng HOSO4210.
- XML130: Đối tượng chứa các thông tin theo định dạng HOSO130.

##### Ví dụ:

###### 1. Cơ bản:

`var xmlObject = new XmlObject(); xmlObject.HOSO = new XmlDocument();`

Ở ví dụ này, chúng ta khởi tạo một đối tượng `XmlObject` và thiết lập thuộc tính `HOSO`.

###### 2. Trung bình:

`var xmlObject = new XmlObject() { HOSO = new XmlDocument(), XML4210 = new HOSO4210(), XML130 = new HOSO130() };`

Ở ví dụ này, chúng ta khởi tạo và thiết lập nhiều thuộc tính cùng một lúc.

###### 3. Phức tạp:

`var xmlObject = new XmlObject(); xmlObject.HOSO.LoadXml(""); xmlObject.XML4210 = new HOSO4210(xmlObject.HOSO); xmlObject.XML130 = new HOSO130(xmlObject.HOSO);`

Ở ví dụ này, chúng ta khởi tạo đối tượng `XmlObject`, tải nội dung XML vào thuộc tính `HOSO`, và khởi tạo các đối tượng `XML4210` và `XML130` dựa trên nội dung của `HOSO`.