好久没有写文章了,终于找到工作,抽空写一下冒个泡。
问题
最近遇到一个这样 ORM 的问题,一个返回类型为 List 泛型方法中,需要做到根据条件访问数据库,并且把得到的结果存入 List 中返回。
由于只是以前学过一段时间的 C#,而且反射一直个人认为是各中难点,加上泛型,这篇文章纯属个人纪录,如有错误,望各位大佬指正。
分析
根据条件访问数据库 ==> 遍历获取到的 reader 对象 ==> 创建泛型实例以及泛型 List,并且对实例赋值存入 List ==> 遍历完成,返回当前的 List
从上面的几个步骤中我们可以发现,难点就是在于这个泛型实例的创建以及它的属性赋值。我们可以通过 Activator 的CreateInstance(type) 方法创建,然后通过 type.setValue(object,value,index) 来设置对应的属性值,至于如何匹配这些属性值,我们就通过 ORM 中来映射获取到对应的特性值与数据库字段的匹配。这样问题就解决了。
解决方法
这里分为几个步骤,
- 获取到数据库的返回(ps:这个比较简单我就不多说了,具体可以直接百度,狗狗都有很多)
- 获取到对应的泛型的类型
这里是通过 typeof() 方法 - 通过获取到的类型由 Activator 类的 CreateInstance(type) 方法创建 object 实例
- 通过 type 获取到此实例的属性列表
- 遍历属性列表,并与 数据库 中的属性对比匹配,得到匹配成功的特性信息。
- 判断特性信息,为空就跳过,不为空就通过 setValue(object,value,index) 方法设置属性的对应值,并添加到 List 中。
代码
private const string SELECT = "SELECT * FROM dbo.Alvin ";
public static List<TEntity> Query<TEntity>(string condition)
{
using (var conn = SqlHelper.Instance.GetConnection())
{
var reader = SqlHelper
.Instance
.ExecuteQuery(conn,
SELECT + condition,
new List<SqlParameter> {
});
List<TEntity> list = new List<TEntity>();
//获取到泛型的类型
Type type = typeof(TEntity);
//通过反射由类型创建对应object实例
object o = Activator.CreateInstance(type);
//通过类型获取到有的属性
var infos = type.GetProperties();
while (reader.Read())
{
//Console.WriteLine("infos 数量:{0}",infos.Length);
foreach (var info in infos)
{
//Console.WriteLine("info 不为空");
//获取到属性对应的特性信息(这里就做了匹配)
object[] ob = info.GetCustomAttributes(typeof(FieldAttribute), false);
if (ob != null)
{
//通过反射设置对应的属性值,o代表与o绑定
info.SetValue(o, reader[((FieldAttribute)ob[0]).Fields], null);
//Console.WriteLine("结果是:{0}", reader[((FieldAttribute)ob[0]).Fields]);
}
}
//添加到list中
list.Add((TEntity)o);
}
return list;
}
}


469

被折叠的 条评论
为什么被折叠?



