版本1:使用反射生成SQL语句并从SqlDataReader中读取数据
public T FindV1<T>(int id) where T : BaseModel
{
Type type = typeof(T);
string columnString = string.Join(",", type.GetProperties().Select(p => $"[{p.GetColumnName()}]"));
string sql = $"SELECT {columnString} FROM [{type.Name}] WHERE Id={id}";
T t = (T)Activator.CreateInstance(type);
using (SqlConnection conn = new SqlConnection(StaticConstant.SqlServerConnString))
{
SqlCommand command = new SqlCommand(sql, conn);
conn.Open();
SqlDataReader reader = command.ExecuteReader();
if (reader.Read())
{
foreach (var prop in type.GetProperties())
{
prop.SetValue(t, reader[prop.Name] is DBNull ? null : reader[prop.Name]);
}
}
}
return t;
}
版本1中使用的技术:
- 反射:通过
typeof(T)获取泛型类型T的Type对象,然后获取类型的属性并生成查询SQL语句。 - 特性:使用
GetColumnName()方法从属性上获取特性,用于生成查询SQL语句中的列名。 - 反射:使用
Activator.CreateInstance(type)创建泛型类型T的实例。 - 反射:遍历泛型类型
T的属性,从SqlDataReader中读取数据并设置到实例的属性。
版本2:使用TSqlHelper生成SQL语句并使用ReaderToList方法
public T FindV2<T>(int id) where T : BaseModel
{
string sql = $"{TSqlHelper<T>.FindSql}{id};";
T t = null;
using (SqlConnection conn = new SqlConnection(StaticConstant.SqlServerConnString))
{
SqlCommand command = new SqlCommand(sql, conn);
conn.Open();
SqlDataReader reader = command.ExecuteReader();
List<T> list = this.ReaderToList<T>(reader);
t = list.FirstOrDefault();
}
return t;
}
版本2中使用的技术:
- 泛型:使用泛型类
TSqlHelper<T>生成查询SQL语句。 - 封装:使用
ReaderToList<T>方法将SqlDataReader中的数据转换为泛型类型T的List。
两个版本的主要区别在于生成查询SQL语句和处理SqlDataReader的方式。版本1使用反射和特性生成SQL语句并从SqlDataReader中读取数据,而版本2则使用泛型类TSqlHelper生成SQL语句并调用ReaderToList方法处理SqlDataReader。