You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
188 lines
7.2 KiB
C#
188 lines
7.2 KiB
C#
using System.Reflection;
|
|
using MySql.Data.MySqlClient;
|
|
using OMS.NET.Common;
|
|
namespace OMS.NET.DbClass{
|
|
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
|
|
public class TableAttribute : Attribute
|
|
{
|
|
public string TableName { get; }
|
|
public TableAttribute(string tableName)
|
|
{
|
|
TableName = tableName;
|
|
}
|
|
}
|
|
|
|
[AttributeUsage(AttributeTargets.Property, Inherited = false)]
|
|
public class ColumnAttribute : Attribute
|
|
{
|
|
public string ColumnName { get; }
|
|
public bool IsPrimaryKey { get; }
|
|
|
|
public bool IsIdentity { get; } // 是否自增列
|
|
public ColumnAttribute(string columnName, bool isPrimaryKey = false, bool isIdentity = false)
|
|
{
|
|
ColumnName = columnName;
|
|
IsPrimaryKey = isPrimaryKey;
|
|
IsIdentity = isIdentity;
|
|
}
|
|
}
|
|
|
|
public class SqlHelper{
|
|
public static string GetTableName(Type type)
|
|
{
|
|
var attr = type.GetCustomAttribute<TableAttribute>();
|
|
return attr?.TableName ?? throw new Exception($"{type.Name} 没有指定数据表");
|
|
}
|
|
|
|
public static IEnumerable<PropertyInfo> GetProperties(Type type)
|
|
{
|
|
return type.GetProperties()
|
|
.Where(p => p.GetCustomAttribute<ColumnAttribute>() != null);
|
|
}
|
|
|
|
private static PropertyInfo GetPrimaryKeyProperties(Type type)
|
|
{
|
|
var primaryKeyProperties = GetProperties(type)
|
|
.Where(p => p.GetCustomAttribute<ColumnAttribute>()?.IsPrimaryKey == true)
|
|
.ToList();
|
|
|
|
if (primaryKeyProperties.Count == 0)
|
|
{
|
|
throw new InvalidOperationException("No primary key defined for the class.");
|
|
}
|
|
|
|
if (primaryKeyProperties.Count != 1)
|
|
{
|
|
throw new InvalidOperationException("Multiple primary keys defined for the class. Only one primary key is allowed.");
|
|
}
|
|
|
|
return primaryKeyProperties.First();
|
|
}
|
|
|
|
private static IEnumerable<PropertyInfo> GetNonKeyProperties(Type type)
|
|
{
|
|
return GetProperties(type)
|
|
.Where(p => p.GetCustomAttribute<ColumnAttribute>()?.IsPrimaryKey == false);
|
|
}
|
|
|
|
private static PropertyInfo? GetIdentityKeyProperty(Type type)
|
|
{
|
|
var primaryKey = GetPrimaryKeyProperties(type);
|
|
return (primaryKey.GetCustomAttribute<ColumnAttribute>()!.IsIdentity == true) ? null : primaryKey;
|
|
}
|
|
|
|
public static string GetInsertSql(Type type)
|
|
{
|
|
var tableName = GetTableName(type);
|
|
var identityKey = GetIdentityKeyProperty(type);
|
|
var columns = GetNonKeyProperties(type)
|
|
.Select(p => p.GetCustomAttribute<ColumnAttribute>()!.ColumnName).ToList();
|
|
var values = GetNonKeyProperties(type)
|
|
.Select(p => "@" + p.Name).ToList();
|
|
|
|
if (identityKey != null)
|
|
{
|
|
// Exclude the identity key from columns and values for insert statement
|
|
columns.Add(identityKey.GetCustomAttribute<ColumnAttribute>()!.ColumnName);
|
|
values.Add("@" + identityKey.Name);
|
|
}
|
|
|
|
return $"INSERT INTO {tableName} ({string.Join(", ", columns)}) VALUES ({string.Join(", ", values)})";
|
|
}
|
|
|
|
public static string GetUpdateSql(Type type)
|
|
{
|
|
var tableName = GetTableName(type);
|
|
var setClause = string.Join(", ",
|
|
GetNonKeyProperties(type)
|
|
.Select(p => $"{p.GetCustomAttribute<ColumnAttribute>()!.ColumnName} = @{p.Name}"));
|
|
var primaryKey = GetPrimaryKeyProperties(type);
|
|
var whereClause = $"{primaryKey.GetCustomAttribute<ColumnAttribute>()!.ColumnName} = @{primaryKey.Name}";
|
|
|
|
return $"UPDATE {tableName} SET {setClause} WHERE {whereClause}";
|
|
}
|
|
|
|
public static string GetDeleteSql(Type type)
|
|
{
|
|
var tableName = GetTableName(type);
|
|
var primaryKey = GetPrimaryKeyProperties(type);
|
|
var whereClause = $"{primaryKey.GetCustomAttribute<ColumnAttribute>()!.ColumnName} = @{primaryKey.Name}";
|
|
|
|
return $"DELETE FROM {tableName} WHERE {whereClause}";
|
|
}
|
|
|
|
public static string GetSelectSql(Type type)
|
|
{
|
|
var tableName = GetTableName(type);
|
|
var columns = string.Join(", ",
|
|
GetProperties(type)
|
|
.Select(p => p.GetCustomAttribute<ColumnAttribute>()!.ColumnName));
|
|
|
|
return $"SELECT {columns} FROM {tableName}";
|
|
}
|
|
|
|
public static string GetSelectSqlWithPrimaryKey(Type type)
|
|
{
|
|
var tableName = GetTableName(type);
|
|
var columns = string.Join(", ",
|
|
GetProperties(type)
|
|
.Select(p => p.GetCustomAttribute<ColumnAttribute>()!.ColumnName));
|
|
var primaryKey = GetPrimaryKeyProperties(type);
|
|
var whereClause = $"{primaryKey.GetCustomAttribute<ColumnAttribute>()!.ColumnName} = @{primaryKey.Name}";
|
|
|
|
return $"SELECT {columns} FROM {tableName} WHERE {whereClause}";
|
|
}
|
|
|
|
public static IEnumerable<T> SelectAll<T>() where T : SqlTable, new()
|
|
{
|
|
var type = typeof(T);
|
|
var selectSql = GetSelectSql(type);
|
|
|
|
using MySqlConnection connection = new(GlobalArea.ConnectionStringWithDbName);
|
|
connection.Open(); // 确保在执行命令之前打开连接
|
|
using var command = new MySqlCommand(selectSql, connection);
|
|
using var reader = command.ExecuteReader();
|
|
var results = new List<T>();
|
|
while (reader.Read())
|
|
{
|
|
var item = new T();
|
|
PopulateObject(reader, item);
|
|
results.Add(item);
|
|
}
|
|
return results;
|
|
}
|
|
|
|
private static void PopulateObject(MySqlDataReader reader, SqlTable obj)
|
|
{
|
|
var type = obj.GetType();
|
|
foreach (var property in GetProperties(type))
|
|
{
|
|
var columnAttr = property.GetCustomAttribute<ColumnAttribute>()!;
|
|
var value = reader[columnAttr.ColumnName];
|
|
if (value != DBNull.Value)
|
|
{
|
|
property.SetValue(obj, Convert.ChangeType(value, property.PropertyType));
|
|
}
|
|
}
|
|
}
|
|
|
|
public static T? Get<T>(object key) where T : SqlTable, new()
|
|
{
|
|
var type = typeof(T);
|
|
var selectSql = GetSelectSqlWithPrimaryKey(type);
|
|
using MySqlConnection connection = new(GlobalArea.ConnectionStringWithDbName);
|
|
connection.Open(); // 确保在执行命令之前打开连接
|
|
using var command = new MySqlCommand(selectSql, connection);
|
|
var primaryKey = GetPrimaryKeyProperties(type);
|
|
command.Parameters.AddWithValue("@" + primaryKey.GetCustomAttribute<ColumnAttribute>()!.ColumnName, key);
|
|
using var reader = command.ExecuteReader();
|
|
while (reader.Read())
|
|
{
|
|
var item = new T();
|
|
PopulateObject(reader, item);
|
|
return item;
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
} |