我希望將我的數據庫查詢結果映射到我的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方法中的代碼。還有什麼需要調整的嗎?
PS:我知道Dapper,我只想自己實現類似的東西,以幫助我更好地學習。
你所做的基本上就是linq-to-sql或其他OR-mappers所做的事情。要了解它是如何工作的細節,從頭開始編寫一些東西總是一個好主意。
如果你想要更多的靈感,或者想要有一些現成的東西可以開箱即用,我建議你閱讀linq-to-sql。它重量輕,但能幹。
我能想到一些事情:
我認為為了跳過循環你可以使用:
reader[item.Name]
我自己做過類似的事情,但我從來沒有遇到過精打細算。我不確定它是否使用反射,但是閱讀其他人的代碼來提高你的技能總是一個好主意(Scott Hanselman經常建議這樣做)。
您還可以查看: http : //www.codeproject.com/KB/database/metaquery_part1.aspx
您可以實現將字段映射到數據庫列的屬性,但這只是為了好玩。
編輯:
5:你也可以跳過閱讀器上的while循環,只取第一行,並記錄你的查詢只返回一個對象的事實,所以如果查詢返回一千行,它就不會拉一千行。