[英]Alternatives to using property.setvalue() for efficiency purposes
property.setvalue()有什么替代方法? 我讀過,這很慢。 我使用它來將IDataReader映射到POCO對象。
這是代碼的截斷版本。 這里的一切對我來說都是新的。 我知道有很多框架可以完成這項任務。 但是,我們不能使用它們。
public class DbAutoMapper<T>
{
public IEnumerable<T> MapToList(IDataReader reader)
{
var list = new List<T>();
while (reader.Read())
{
var obj = Activator.CreateInstance<T>();
foreach (PropertyInfo prop in obj.GetType().GetProperties())
{
foreach (var attribute in prop.GetCustomAttributes(true))
{
prop.SetValue(obj, value, null);
}
}
list.Add(obj);
}
return list;
}
}
首先:當不使用屬性時,為什么要為每個屬性重復反射?
第二:假設您打算按名稱(從列到屬性)進行映射(這不是當前代碼執行的操作),請考慮使用像dapper之類的工具,它可以為您完成所有這些工作 ,包括緩存的高性能反射發射。 它還將為您自己處理命令。 例如:
string region = "North";
var customers = conn.Query<Customer>(
@"select * from Customers where Region = @region",
new { region } // full parameterization, the easy way
).ToList();
如果您需要更多控制權,請考慮FastMember ,它提供快速的成員訪問(再次是反射發射),但並不特定於數據訪問:
var accessor = TypeAccessor.Create(typeof(T));
string propName = // something known only at runtime
while( /* some loop of data */ ) {
var obj = new T();
foreach(var col in cols) {
string propName = // ...
object cellValue = // ...
accessor[obj, propName] = cellValue;
}
yield return obj;
}
我想到了幾種方法...
跳過反射
public class DbAutoMapper<T> where T : IInitFromReader, new()
{
public IEnumerable<T> MapToList(IDataReader reader)
{
var list = new List<T>();
while (reader.Read())
{
IInitFromReader obj = new T;
obj.InitFromReader(reader);
list.Add(obj);
}
return list;
}
}
然后,您必須在每個實體對象中實現InitFromReader。 顯然,這跳過了反射(更少的代碼)的好處。
代碼生成
為(InitFromReader)維護此代碼很麻煩,因此您可以選擇生成它。 這在很多方面都為您提供了兩全其美的方法:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.