2025-07-21 18:36:09 +08:00
|
|
|
|
using System;
|
|
|
|
|
using System.Data;
|
|
|
|
|
using MySqlConnector;
|
|
|
|
|
|
|
|
|
|
namespace DBObj
|
|
|
|
|
{
|
|
|
|
|
public class MyDB : IDisposable
|
|
|
|
|
{
|
2025-07-28 16:22:24 +08:00
|
|
|
|
|
2025-07-21 18:36:09 +08:00
|
|
|
|
private readonly string connectionString = Utils.Env.GetDBConnection();
|
|
|
|
|
private MySqlConnection conn;
|
2025-07-28 16:22:24 +08:00
|
|
|
|
private DataTable table = new DataTable();
|
|
|
|
|
private int cursor = 0;
|
2025-07-21 18:36:09 +08:00
|
|
|
|
|
|
|
|
|
public MyDB()
|
|
|
|
|
{
|
|
|
|
|
conn = new MySqlConnection(connectionString);
|
|
|
|
|
conn.Open();
|
2025-07-28 16:22:24 +08:00
|
|
|
|
//Console.WriteLine("MyDB 連線成功!");
|
2025-07-21 18:36:09 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
|
|
|
|
if (conn != null)
|
|
|
|
|
{
|
2025-07-28 16:22:24 +08:00
|
|
|
|
conn.Dispose(); // 包含 Close + 資源釋放
|
|
|
|
|
conn = null;
|
|
|
|
|
//Console.WriteLine("MyDB 連線已釋放!");
|
2025-07-21 18:36:09 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SELECT 方法
|
2025-07-28 16:22:24 +08:00
|
|
|
|
public bool open(string query, MySqlParameter[] parameters, bool showError = true)
|
2025-07-21 18:36:09 +08:00
|
|
|
|
{
|
2025-07-28 16:22:24 +08:00
|
|
|
|
table.Clear();
|
|
|
|
|
cursor = 0;
|
|
|
|
|
try
|
2025-07-21 18:36:09 +08:00
|
|
|
|
{
|
2025-07-28 16:22:24 +08:00
|
|
|
|
using (var cmd = new MySqlCommand(query, conn))
|
2025-07-21 18:36:09 +08:00
|
|
|
|
{
|
2025-07-28 16:22:24 +08:00
|
|
|
|
if (parameters != null)
|
|
|
|
|
{
|
|
|
|
|
cmd.Parameters.AddRange(parameters);
|
|
|
|
|
}
|
|
|
|
|
using (var adapter = new MySqlDataAdapter(cmd))
|
|
|
|
|
{
|
|
|
|
|
adapter.Fill(table);
|
|
|
|
|
}
|
2025-07-21 18:36:09 +08:00
|
|
|
|
}
|
2025-07-28 16:22:24 +08:00
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
if (showError)
|
|
|
|
|
Console.WriteLine($"DB Error: {ex.Message}");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
public T Field<T>(string name)
|
|
|
|
|
{
|
|
|
|
|
if (cursor < 0 || cursor >= table.Rows.Count || !table.Columns.Contains(name))
|
|
|
|
|
return default;
|
|
|
|
|
|
|
|
|
|
object value = table.Rows[cursor][name];
|
|
|
|
|
if (value == DBNull.Value)
|
|
|
|
|
return default;
|
|
|
|
|
|
|
|
|
|
return (T)Convert.ChangeType(value, typeof(T));
|
|
|
|
|
}
|
|
|
|
|
public List<T> ToList<T>() where T : new()
|
|
|
|
|
{
|
|
|
|
|
var list = new List<T>();
|
|
|
|
|
|
|
|
|
|
foreach (DataRow row in table.Rows)
|
|
|
|
|
{
|
|
|
|
|
T obj = new T();
|
|
|
|
|
foreach (DataColumn col in table.Columns)
|
2025-07-21 18:36:09 +08:00
|
|
|
|
{
|
2025-07-28 16:22:24 +08:00
|
|
|
|
var prop = typeof(T).GetProperty(col.ColumnName,
|
|
|
|
|
System.Reflection.BindingFlags.Public |
|
|
|
|
|
System.Reflection.BindingFlags.Instance |
|
|
|
|
|
System.Reflection.BindingFlags.IgnoreCase);
|
|
|
|
|
|
|
|
|
|
if (prop != null && prop.CanWrite)
|
|
|
|
|
{
|
|
|
|
|
object value = row[col];
|
|
|
|
|
if (value == DBNull.Value)
|
|
|
|
|
{
|
|
|
|
|
value = null;
|
|
|
|
|
}
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (value != null && prop.PropertyType != value.GetType())
|
|
|
|
|
{
|
|
|
|
|
value = Convert.ChangeType(value, prop.PropertyType);
|
|
|
|
|
}
|
|
|
|
|
prop.SetValue(obj, value);
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
// 可以視情況加入錯誤處理
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-07-21 18:36:09 +08:00
|
|
|
|
}
|
2025-07-28 16:22:24 +08:00
|
|
|
|
list.Add(obj);
|
2025-07-21 18:36:09 +08:00
|
|
|
|
}
|
2025-07-28 16:22:24 +08:00
|
|
|
|
|
|
|
|
|
return list;
|
2025-07-21 18:36:09 +08:00
|
|
|
|
}
|
2025-07-28 16:22:24 +08:00
|
|
|
|
public Dictionary<string, object> CurrentRowAsDictionary()
|
|
|
|
|
{
|
|
|
|
|
if (cursor < 0 || cursor >= table.Rows.Count)
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
var dict = new Dictionary<string, object>();
|
|
|
|
|
foreach (DataColumn col in table.Columns)
|
|
|
|
|
{
|
|
|
|
|
dict[col.ColumnName] = table.Rows[cursor][col];
|
|
|
|
|
}
|
|
|
|
|
return dict;
|
|
|
|
|
}
|
2025-08-11 17:36:01 +08:00
|
|
|
|
public void moveNext() => cursor++;
|
|
|
|
|
public void movePrevious() => cursor--;
|
|
|
|
|
public void move(int index) => cursor = index;
|
|
|
|
|
public void moveFirst() => cursor = 0;
|
|
|
|
|
public void moveEnd() => cursor = table.Rows.Count - 1;
|
|
|
|
|
public bool bof() => (cursor < 0) || (table.Rows.Count == 0);
|
|
|
|
|
public bool eof() => cursor > table.Rows.Count - 1;
|
2025-07-28 16:22:24 +08:00
|
|
|
|
public bool Read()
|
|
|
|
|
{
|
|
|
|
|
if (eof()) return false;
|
|
|
|
|
moveNext();
|
|
|
|
|
return !eof();
|
|
|
|
|
}
|
2025-08-11 17:36:01 +08:00
|
|
|
|
public int recordCount() => table.Rows.Count;
|
|
|
|
|
public bool found() => table.Rows.Count > 0;
|
|
|
|
|
public void clear() => table.Clear();
|
|
|
|
|
|
2025-07-21 18:36:09 +08:00
|
|
|
|
// INSERT / UPDATE / DELETE 方法
|
|
|
|
|
public int ExecuteNonQuery(string query, MySqlParameter[] parameters)
|
|
|
|
|
{
|
|
|
|
|
using (var cmd = new MySqlCommand(query, conn))
|
|
|
|
|
{
|
|
|
|
|
if (parameters != null)
|
|
|
|
|
{
|
|
|
|
|
cmd.Parameters.AddRange(parameters);
|
|
|
|
|
}
|
|
|
|
|
return cmd.ExecuteNonQuery();
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-07-28 16:22:24 +08:00
|
|
|
|
public long LastInsertId()
|
|
|
|
|
{
|
|
|
|
|
using (var cmd = new MySqlCommand("SELECT LAST_INSERT_ID()", conn))
|
|
|
|
|
{
|
|
|
|
|
return Convert.ToInt64(cmd.ExecuteScalar());
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-07-21 18:36:09 +08:00
|
|
|
|
}
|
|
|
|
|
}
|