修复 Excel 无法表示 1900 年之前日期的问题
# DbTable ʹÓÃ˵Ã÷
`NewLife.Data.DbTable` ÊÇÒ»¸öÇáÁ¿¼¶µÄ±í¸ñÊý¾ÝÈÝÆ÷£¬Ö§³Ö´ÓÊý¾Ý¿â¶ÁÈ¡¡¢¶þ½øÖÆ/Xml/Csv ÐòÁл¯¡¢Óë `DataTable` »¥×ª£¬ÒÔ¼°Ä£ÐͶÔÏóÓëÐÐÖ®¼äµÄÓ³Éä¡£
- ÃüÃû¿Õ¼ä£º`NewLife.Data`
- Ö÷ÒªÀàÐÍ£º`DbTable`¡¢`DbRow`
- µäÐͳ¡¾°£º
- ´Ó `IDataReader`/`DbDataReader` ¶ÁÈ¡²éѯ½á¹û
- Óë `DataTable` »¥×ª£¬Ìá¸ßÓë ADO.NET µÄ»¥²Ù×÷
- ½«±íÊý¾ÝÐòÁл¯Îª¶þ½øÖÆ¡¢XML¡¢CSV »òÊý¾Ý°ü
- ½«Ä£ÐÍÁбíдÈëΪ±í£¬»ò½«±í¶ÁȡΪģÐÍÁбí
## ºËÐijÉÔ±
- Áж¨Òå
- `string[] Columns` ÁÐÃû¼¯ºÏ
- `Type[] Types` ÁÐÀàÐͼ¯ºÏ
- Êý¾Ý
- `IList<object?[]> Rows` Ðм¯ºÏ
- `int Total` ×ÜÐÐÊý
- ¶ÁÈ¡
- `Read(IDataReader dr)` / `ReadAsync(DbDataReader dr)`
- `ReadData(IDataReader dr, int[]? fields = null)`£º½ö¶Áȡָ¶¨ÁУ¬`fields[i]` ±íʾԴÊý¾ÝÁÐË÷ÒýÓ³É䵽Ŀ±êÁÐ `i`
- `Read(DataTable table)` ´Ó `DataTable` ¶ÁÈ¡
- ¶þ½øÖƶÁÈ¡£º`Read(Stream)`¡¢`ReadHeader(Binary)`¡¢`ReadData(Binary, rows)`¡¢`ReadRows(Binary, rows)`
- Îļþ/Êý¾Ý°ü£º`LoadFile(path)`¡¢`LoadRows(path)`¡¢`Read(IPacket)`¡¢`Read(byte[])`
- дÈë
- `Write(Stream)`/`WriteHeader(Binary)`/`WriteData(Binary)`/`WriteData(Binary, int[] fields)`
- `WriteRows(Binary, IEnumerable<object?[]>, int[]? fields = null)`/`WriteRow(...)`
- `SaveFile(path)`/`SaveRows(path, rows, fields)`
- `ToPacket()` תÊý¾Ý°ü
- ת»»
- `ToDataTable()`/`Write(DataTable)`
- `ToJson(...)`/`WriteXml(Stream)`/`GetXml()`/`SaveCsv(path)`/`LoadCsv(path)`
- Ä£ÐÍÓ³Éä
- `WriteModels<T>(IEnumerable<T>)` ½«Ä£ÐÍдÈëΪ±í£¨½ö»ù´¡ÀàÐÍÊôÐÔ£©
- `Cast<T>(IEnumerable<T>)` ½«Ä£ÐͰ´ÁÐ˳ÐòתΪÐÐ
- `ReadModels<T>()`/`ReadModels(Type)` ½«±íתΪģÐÍÁбí
- ·ÃÎÊ
- `Get<T>(rowIndex, name)`/`TryGet<T>(rowIndex, name, out value)`
- `GetColumn(name)` ¸ù¾ÝÁÐÃûÕÒË÷Òý
- ö¾Ù£º`foreach (var row in table)`£¬Ã¿¸ö `row` ÊÇ `DbRow`
## ¿ìËÙÉÏÊÖ
### 1) ´ÓÊý¾Ý¿â¶ÁÈ¡
```csharp
using var cmd = connection.CreateCommand();
cmd.CommandText = "select Id, Name, CreateTime from User";
using var reader = cmd.ExecuteReader();
var table = new DbTable();
table.Read(reader);
Console.WriteLine(table.Total); // ÐÐÊý
Console.WriteLine(table.Columns[0]); // ÁÐÃû
```
½öÑ¡Ôñ²¿·ÖÁУº
```csharp
// fields: ½«Ä¿±êÁÐ i Ó³Éäµ½Ô´ reader µÄÁÐË÷Òý fields[i]
// ÀýÈçÖ»¶ÁµÚ 0 ºÍµÚ 2 ÁÐ
int[] fields = [0, 2];
var table = new DbTable();
table.ReadHeader(reader); // ÏȶÁÈ¡Áж¨Òå
table.ReadData(reader, fields);
```
### 2) Óë DataTable »¥×ª
```csharp
var dataTable = table.ToDataTable();
var table2 = new DbTable();
table2.Read(dataTable);
```
### 3) ÐòÁл¯
- ¶þ½øÖÆ£º
```csharp
using var fs = File.Create("users.db");
table.SaveFile("users.db"); // »ò table.Write(fs)
var t2 = new DbTable();
t2.LoadFile("users.db");
```
- XML/Csv£º
```csharp
var xml = table.GetXml();
table.SaveCsv("users.csv");
```
- Êý¾Ý°ü£º
```csharp
var pk = table.ToPacket();
```
### 4) Ä£ÐÍÓ³Éä
```csharp
public sealed class User
{
public Int32 Id { get; set; }
public String Name { get; set; } = "";
public DateTime CreateTime { get; set; }
}
// Ä£ÐÍ -> ±í
var users = new List<User> { new() { Id = 1, Name = "Stone", CreateTime = DateTime.UtcNow } };
var table = new DbTable();
table.WriteModels(users);
// ±í -> Ä£ÐÍ
var list = table.ReadModels<User>().ToList();
```
## ½ø½×˵Ã÷
- `fields` Ó³É乿Ôò
- ¶ÁÈ¡£º`ReadData(dr, fields)` ½«Ä¿±êÁÐ `i` Ó³Éäµ½Ô´ÁÐË÷Òý `fields[i]`£¬¿ÕÖµ»á°´Ô´ÁÐÀàÐÍÌî³äĬÈÏÖµ£¨ÊýÖµ 0¡¢`false`¡¢`DateTime.MinValue` µÈ£©¡£
- дÈ룺`WriteData(bn, fields)`/`WriteRow(bn, row, fields)` ½«Ä¿±êÁÐ `i` дÈëÔ´ÐÐµÄ `row[fields[i]]`£»Èô `fields[i] == -1` Ôò°´Ä¿±êÁÐÀàÐÍдÈë¿ÕÖµ¡£
- Èç¹ûÒÔµü´úÆ÷·½Ê½Ïû·Ñ£º`ReadRows(bn, -1)` ¿É³ÖÐø¶ÁÈ¡ÖÁÁ÷ĩβ¡£
- `DbRow` Ìṩ¿ì½Ý·ÃÎÊ£º`row.Get<T>("Name")`¡£
## ¼æÈÝÓë×¢Òâ
- ¶þ½øÖƸñʽͷº¬»ÃÊýÓë°æ±¾£¬µ±Ç°°æ±¾ `3`£¬Ïòǰ¼æÈݾɰ汾ʱ¼äдÈë¸ñʽ¡£
- MySQL ÌØÊâÈÕÆÚ£¨Èç `0000-00-00`£©¿ÉÄÜÔÚ¶ÁȡʱÒì³££¬ÄÚ²¿ÒÑÓà `try/catch` ºöÂÔ²¢Ìî³äĬÈÏÖµ¡£
- ¸ßÐÔÄÜ·¾¶±ÜÃâ´óÁ¿ LINQ/·´É䣻ÀàÐÍ¡¢ÁÐÃûµÈÒÑ»º´æÓÚ `DbTable` µÄ `Columns`/`Types`¡£
## ±ä¸üÕªÒª£¨±¾´ÎÖØ¹¹£©
- ÐÞ¸´ `ReadData/ReadDataAsync` ÔÚ `fields` Ó³É䳡¾°ÏµÄÀàÐÍË÷Òý´íλÎÊÌâ¡£
- ÐÞ¸´ `WriteData(Binary, int[])` Óë `WriteRow(Binary, object?[], int[]?)` ÔÚ `idx < 0` ʱԽ½ç·ÃÎÊ `ts[idx]` µÄÎÊÌ⣬¸ÄΪ°´Ä¿±êÁÐÀàÐÍдÈë¿ÕÖµ¡£
- `Read(DataTable)` ÉèÖà `Total` ÓëÆäËû¶ÁÈ¡·½Ê½±£³ÖÒ»Ö¡£
- `GetXml()` ¸ÄΪͬ²½µÈ´ý `WriteXml` Íê³É£¬±ÜÃâ `Wait(15000)` ¿ÉÄܵ¼ÖÂÄÚÈݲ»ÍêÕû¡£
- ¸Ä½øÃ¶¾ÙÆ÷ʵÏÖ£¬Ö§³Ö `Reset()` ºóÖØÐÂö¾Ù¡£
## ²Î¿¼
- Îĵµ£ºhttps://newlifex.com/core/dbtable
- ÃüÃû¿Õ¼ä£º`NewLife.Data`
|