Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I created a hashtable to cache the reflection results. First time, it's neccessary to make a call to GetProperties and store the results into the hastable. Next times, first check the hashtable for the List of PropertyInfo objects. If exists, use it. If not, invoke GetProperties.</p> <p>I use this to map a datareader to a List of Entities.</p> <p>My implementation is based on: <a href="http://www.simple-talk.com/dotnet/.net-framework/a-defense-of-reflection-in-.net/" rel="nofollow">A Defense on Reflection in .Net</a>, by Nick Harrison (<a href="http://www.simple-talk.com/dotnet/.net-framework/a-defense-of-reflection-in-.net/" rel="nofollow">http://www.simple-talk.com/dotnet/.net-framework/a-defense-of-reflection-in-.net/</a>).</p> <p>So, there it is:</p> <pre><code>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&lt;PropertyInfo&gt; propertyList = new List&lt;PropertyInfo&gt;(); 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&lt;PropertyInfo&gt; propertyList = new List&lt;PropertyInfo&gt;(); PropertyInfo[] objectProperties = targetType.GetProperties(flags); foreach (PropertyInfo currentProperty in objectProperties) { propertyList.Add(currentProperty); } properties[targetType.FullName] = propertyList; } } public void MapearDataReaderListaObjetos &lt;T&gt; (IDataReader dr, List&lt;T&gt; lista) where T: new() { Type businessEntityType = typeof(T); List&lt;T&gt; entitys = new List&lt;T&gt;(); T miObjeto = new T(); LoadProperties(miObjeto, businessEntityType); List&lt;PropertyInfo&gt; sourcePoperties = Properties[businessEntityType.FullName] as List&lt;PropertyInfo&gt;; while (dr.Read()) { T newObject = new T(); for (int index = 0; index &lt; dr.FieldCount; index++) { for (int _indice = 0; _indice &lt; 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) &amp;&amp; info.CanWrite) { info.SetValue(newObject, dr.GetValue(index), null); } } } } entitys.Add(newObject); } dr.Close(); lista = entitys; } } </code></pre> <p>Then, I call it from my DataAcces Layer, like this:</p> <pre><code>public List &lt;Entities.ENFactura&gt; ListaxIdFactura (SqlTransaction Tr, Entities.ENFactura oBEFactura) { SqlConnection Cn = new SqlConnection(); Cn = _Connection.ConexionSEG(); List&lt;Entities.ENFactura&gt; loBEFactura = new List&lt;Entities.ENFactura&gt;(); 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 &lt;ENFactura&gt;(drd, loBEFactura); } } } return (loBEFactura); } </code></pre> <p>So, this way, the DAL gets a datareader, map it to a list of business entities, and return it to the Business Logic Layer.</p> <p>This class (MapeadorDataReaderListaObjetos) has some issues still, particularly at:</p> <pre><code>info.SetValue(newObject, _valor, null); </code></pre> <p>newObject and _valor must be the same type or you'll get an exception (conversion from System.Int64 to System.Int32, in case your entity property is Int32 and its corresponding field at the database table is bigint, for example).</p> <p>Also, if an entity property is another entity, this will not work, because datareaders do not return entity objects.</p> <p>Obviously, this can be improved.</p> <p>Regarding reflection and delegates, i found this article: Reflection - Slow or Fast? Demonstration with Solutions, by Abhishek Sur, at <a href="http://www.abhisheksur.com/2010/11/reflection-slow-or-faster-demonstration.html" rel="nofollow">http://www.abhisheksur.com/2010/11/reflection-slow-or-faster-demonstration.html</a></p> <p>Another good article is: Dodge Common Performance Pitfalls to Craft Speedy Applications, by Joel Pobar, at <a href="http://msdn.microsoft.com/en-us/magazine/cc163759.aspx" rel="nofollow">http://msdn.microsoft.com/en-us/magazine/cc163759.aspx</a>.</p> <p>Hope this helps.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload