我希望将我的数据库查询结果映射到我的c#代码中的强类型对象。所以我在SqlConnection类上编写了一个快速而又脏的辅助方法,它在数据库上运行查询并使用反射将记录列映射到对象属性。代码如下:
public static T Query<T>(this SqlConnection conn, string query) where T : new()
{
T obj = default(T);
using (SqlCommand command = new SqlCommand(query, conn))
{
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
obj = new T();
PropertyInfo[] propertyInfos;
propertyInfos = typeof(T).GetProperties();
for (int i = 0; i < reader.FieldCount; i++)
{
var name = reader.GetName(i);
foreach (var item in propertyInfos)
{
if (item.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase) && item.CanWrite)
{
item.SetValue(obj, reader[i], null);
}
}
}
}
}
}
return obj;
}
public class User
{
public int id { get; set; }
public string firstname { get; set; }
public string lastname { get; set; }
public DateTime signupDate { get; set; }
public int age { get; set; }
public string gender { get; set; }
}
var user = conn.Query<User>("select id,firstname,lastname from users");
我只想在上面的方法中使用反射来将值组合在一起,如果有任何我可以在上面的代码中做得更好的话。或者,如果有其他完全不同的方法,我可以采取相同的结果?
我想我可以通过删除propertyInfos的循环并使用字典来改进helper方法中的代码。还有什么需要调整的吗?
P.S:我知道Dapper,我只想自己实现类似的东西,以帮助我更好地学习。答案 0 :(得分:2)
你所做的基本上是linq-to-sql或其他OR-mappers所做的事情。要了解它是如何工作的细节,从头开始写一些东西总是一个好主意。
如果你想要更多的灵感或者希望有一些可以开箱即用的产品,我建议你阅读linq-to-sql。它重量轻,但能干。
答案 1 :(得分:0)
我可以想到一些事情:
我认为为了跳过循环你可以使用:
reader[item.Name]
我自己做过类似的事,但我从来没有遇到过精打细算。我不确定它是否使用反射,但是阅读其他人的代码来提高你的技能总是一个好主意(Scott Hanselman经常建议这样做)。
您还可以查看: http://www.codeproject.com/KB/database/metaquery_part1.aspx
您可以实现将字段映射到数据库列的属性,但这只是为了好玩。
编辑:
5:你也可以跳过阅读器上的while循环,只取第一行,并记录你的查询只返回一个对象的事实,所以如果查询返回一千行,它就不会拉一千行