私は、反映結果をキャッシュするためのハッシュテーブルを作成しました。初めて、GetPropertiesを呼び出し、その結果をhastableに保存する必要があります。次回は、まずPropertyInfoオブジェクトのListのハッシュテーブルをチェックしてください。存在する場合は、それを使用します。そうでなければ、GetPropertiesを呼び出します。
これを使用して、データウェアハウスをエンティティのリストにマップします。
私の実装は、Nick Harrison(http://www.simple-talk.com/dotnet/.net-framework/a-defense-of-reflection-in-.net/)のA Defense on Reflection in .Netに基づいています。
だから、そこにそれがある:だから
public List <Entities.ENFactura> ListaxIdFactura (SqlTransaction Tr, Entities.ENFactura oBEFactura)
{
SqlConnection Cn = new SqlConnection();
Cn = _Connection.ConexionSEG();
List<Entities.ENFactura> loBEFactura = new List<Entities.ENFactura>();
using (Cn)
{
Cn.Open();
SqlDataReader drd = (odaSQL.fSelDrd(Cn, Tr, "Pa_CC_Factura_Listar_x_IdProveedor", oBEFactura));
if (drd != null)
{
if (drd.HasRows)
{
mapeador.MapearDataReaderListaObjetos <ENFactura>(drd, loBEFactura);
}
}
}
return (loBEFactura);
}
、この方法は、DALは、DataReaderオブジェクトを取得し、それをマップ:
その後
public class MapeadorDataReaderListaObjetos
{
private Hashtable properties;
private Hashtable Properties
{
get
{
if (properties == null)
properties = new Hashtable();
return properties;
}
set { properties = value; }
}
private void LoadProperties(object targetObject, Type targetType)
{
var flags = BindingFlags.DeclaredOnly| BindingFlags.Instance| BindingFlags.Public;
if (properties == null)
{
List<PropertyInfo> propertyList = new List<PropertyInfo>();
PropertyInfo[] objectProperties = targetType.GetProperties(flags);
foreach (PropertyInfo currentProperty in objectProperties)
{
propertyList.Add(currentProperty);
}
properties = new Hashtable();
properties[targetType.FullName] = propertyList;
}
if (properties[targetType.FullName] == null)
{
List<PropertyInfo> propertyList = new List<PropertyInfo>();
PropertyInfo[] objectProperties = targetType.GetProperties(flags);
foreach (PropertyInfo currentProperty in objectProperties)
{
propertyList.Add(currentProperty);
}
properties[targetType.FullName] = propertyList;
}
}
public void MapearDataReaderListaObjetos <T> (IDataReader dr, List<T> lista) where T: new()
{
Type businessEntityType = typeof(T);
List<T> entitys = new List<T>();
T miObjeto = new T();
LoadProperties(miObjeto, businessEntityType);
List<PropertyInfo> sourcePoperties = Properties[businessEntityType.FullName] as List<PropertyInfo>;
while (dr.Read())
{
T newObject = new T();
for (int index = 0; index < dr.FieldCount; index++)
{
for (int _indice = 0; _indice < sourcePoperties.Count; _indice++)
{
if (sourcePoperties[_indice].Name.ToUpper() == dr.GetName(index).ToUpper());
{
string _tipoProp = sourcePoperties[_indice].PropertyType.ToString();
PropertyInfo info = sourcePoperties[_indice] as PropertyInfo;
if ((info != null) && info.CanWrite)
{
info.SetValue(newObject, dr.GetValue(index), null);
}
}
}
}
entitys.Add(newObject);
}
dr.Close();
lista = entitys;
}
}
、私はこのように、私のDataAccesレイヤからそれを呼び出しますビジネスエンティティのリストに追加し、それをビジネスロジックレイヤーに戻します。
info.SetValue(newObject, _valor, null);
でnewObjectと_valorは同じ型でなければならないか、例外(可能System.Int32へSystem.Int64からの変換を、取得します:
このクラス(MapeadorDataReaderListaObjetos)は特にで、まだいくつかの問題を持っていますエンティティプロパティがInt32で、データベーステーブルの対応するフィールドがbigintの場合など)。
また、エンティティプロパティが別のエンティティである場合、データプレイヤーはエンティティオブジェクトを返さないため、これは機能しません。
これは明らかに改善することができます。
反射と代議員に関して、私はこの記事を見つけました:Reflection - SlowまたはFast?ソリューションによるデモンストレーションは、アビシェーク・スルによって、 http://www.abhisheksur.com/2010/11/reflection-slow-or-faster-demonstration.html
で別の良い記事があります:Dodge一般的なパフォーマンスの落とし穴http://msdn.microsoft.com/en-us/magazine/cc163759.aspxで、ジョエルPobarにより、スピーディアプリケーションを作るために。
これが役に立ちます。
実際にはGetPropertyよりも速い(PropertyInfoをキャッシュする方法)が私には示唆されていましたが、まだそれほど時間はかかりませんでしたが、ページの応答性は向上しています。 – Alex
代理人をキャッシュしてタイプセーフな方法で、それはもう一度速くすることができます。間違いなくそれを時間... –