使用反射实现通用SQL数据查询助手
传统SQL查询方法存在重复代码问题,每个实体类需单独实现查询逻辑。以下通过反射机制构建通用查询工具类:
传统查询方法示例
public Student GetStudent(int id)
{
const string sql = "SELECT * FROM Students WHERE StudentId=@Id";
using (var connection = new SqlConnection(_connectionString))
{
var command = new SqlCommand(sql, connection);
command.Parameters.AddWithValue("@Id", id);
connection.Open();
using (var reader = command.ExecuteReader())
{
if (reader.Read())
{
return new Student
{
Id = (int)reader["StudentId"],
Name = reader["StudentName"].ToString(),
Gender = reader["Gender"].ToString(),
BirthDate = (DateTime)reader["DateOfBirth"]
};
}
return null;
}
}
}
该方法仅适用于Student类,其他实体需重复编写相似代码。
反射实现通用查询
public T RetrieveEntity<T>(int id, string idColumn) where T : new()
{
Type entityType = typeof(T);
var properties = entityType.GetProperties();
string columns = string.Join(",", properties.Select(p => p.Name));
string sql = $"SELECT {columns} FROM {entityType.Name} WHERE {idColumn}=@Id";
using (var conn = new SqlConnection(_connString))
{
var cmd = new SqlCommand(sql, conn);
cmd.Parameters.AddWithValue("@Id", id);
conn.Open();
using (var reader = cmd.ExecuteReader())
{
if (reader.Read())
{
var entity = new T();
foreach (var prop in properties)
{
prop.SetValue(entity, reader[prop.Name]);
}
return entity;
}
return default(T);
}
}
}
该方法通过以下方式实现通用性:
1. 动态构建SELECT语句的列名和表名
2. 使用泛型类型创建实例
3. 通过反射将查询结果映射到对象属性
使用示例
实体类定义:
public class Student
{
public int StudentId { get; set; }
public string StudentName { get; set; }
public string Gender { get; set; }
public DateTime DateOfBirth { get; set; }
}
调用通用方法:
var helper = new SqlHelper();
Student entity = helper.RetrieveEntity<Student>(1001, "StudentId");