Login Login
MORE

WIDGETS

Widgets

Wanted articles
Who is online?
Article tools

CSharp:Automatismo caricamento Entità

From Aino Wiki

Jump to: navigation, search

Helper di trasformazione: DataRow-->CustomObject

Esempio 1

        public static T GetEntity<T>(DataRow dr)
        {
            bool columnCanNotCorrespond = true;
            return GetEntity<T>(dr, columnCanNotCorrespond);
        }
        /// <summary>
        /// Riempie una Entità con i valori presenti in un DataRow automaticamente. Se un valore è NULLO inserirà il valore di default.
        /// L'automatismo funzione solo se i nomi delle colonne (campi del DataBase) corrispondono ai nomi 
        /// delle properties se una Property non ha colonna del DataRow semplicemente è valorizzata al Default
        /// (come dopo una istanzizione dell'oggetto mediante "new"). Se una colonna esiste ma non c'è la 
        /// corrispondente proprietà la segnalazione dell'eccezione dipenderà dal flag: columnCanNotCorrespond
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dr"></param>
        /// <param name="columnCanNotCorrespond">Se true, non scatta eccezione se c'è una colonna che non è corrispondente ad una Property</param>
        /// <returns></returns>
        public static T GetEntity<T>(DataRow dr, bool columnCanNotCorrespond)
        {
            Type entityType = typeof(T);
            T entity = (T)entityType.Assembly.CreateInstance(entityType.FullName);
 
            if (columnCanNotCorrespond)
            {
                foreach (DataColumn dc in dr.Table.Columns)
                {
                    object columnValue = dr[dc.ColumnName];
                    //La Property Esiste?
                    if (entity.GetType().GetProperty(dc.ColumnName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase) != null) 
                    {
                        //Assegnazione condizionata affinchè rimanga il valore di Default nel caso il valore da inserire sia nullo 
                        if (columnValue != DBNull.Value) 
                        {
                            entity.GetType().GetProperty(dc.ColumnName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase).SetValue(entity, columnValue, null);
                        }
                    }
                }
            }
            else //Scatterà eccezione se la Property non corrisponde alla colonna!
            {
                foreach (DataColumn dc in dr.Table.Columns)
                {
                    object columnValue = dr[dc.ColumnName];
                    //Assegnazione condizionata affinchè rimanga il valore di Default nel caso il valore da inserire sia nullo 
                    if (columnValue != DBNull.Value)
                    {
                        entity.GetType().GetProperty(dc.ColumnName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase).SetValue(entity, columnValue, null);
                    }
                }
            }
            return (T)entity;
        }

Esempio 2

private static Dictionary<string, PropertyInfo[]> _entitiesFields = new Dictionary<string, PropertyInfo[]>();
 
        /// <summary>
        /// Data una DataRow, restituisce un'entità
        /// </summary>
        /// <param name="dr"></param>
        /// <param name="Entity"></param>
        /// <returns></returns>
        private static T FromDataRowToEntity<T>(DataRow dr) where T : new()
        {
            T result = new T();
 
            if (result != null && dr != null)
            {
                string fullyName = typeof(T).FullName;
                lock (_entitiesFields)
                {
                    if (!_entitiesFields.ContainsKey(fullyName))
                    {
                        // Ottengo tutti i campi della entity
                        _entitiesFields.Add(fullyName, result.GetType().GetProperties());
                    }
                }
 
                PropertyInfo[] properties = _entitiesFields[fullyName];
 
                if (properties != null)
                {
                    for (int i = 0; i < properties.Length; i++)
                    {
                        #region per ogni campo dell'entità, cerco il valore nella riga e glielo assegno
                        PropertyInfo property = properties[i];
                        string propertyName = property.Name;
                        if (dr.Table.Columns.Contains(propertyName))
                            property.SetValue(result, GetFieldValue(property, dr[propertyName]), null);
                        #endregion
                    }
                }
            }
            return result;
        }
 
        /// <summary>
        /// Data una DataTable, restituisce una collezione di entità
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        private static List<T> FromDataTableToListOfEntity<T>(DataTable dt) where T : new()
        {
            List<T> tmp_list = new List<T>();
            if (dt != null)
            {
                foreach (DataRow dr in dt.Rows)
                {
                    T toAdd = FromDataRowToEntity<T>(dr);
                    if (toAdd != null) tmp_list.Add(toAdd);
                }
            }
 
            return tmp_list;
        }

Helper mapping e copia: CustomObject1-->CustomObject2

Versione semplificata:

private static T MapCustom<T>(object entitySource)
{
	Type entityDestType = typeof(T);
	Type entitySourceType = entitySource.GetType();
	T entityDestination = (T)entityDestType.Assembly.CreateInstance(entityDestType.FullName);
 
	foreach (PropertyInfo piSrc in entitySourceType.GetProperties(BindingFlags.FlattenHierarchy // Mamber static and public, nested type are not returned
																))
	{
		if (piSrc.CanRead)
		{
			foreach (PropertyInfo piDst in entityDestType.GetProperties(BindingFlags.FlattenHierarchy // Nested type are not returned
																		))
			{
				if (piSrc.Name.Equals(piDst.Name, StringComparison.InvariantCultureIgnoreCase))
				{
					if (piSrc.PropertyType == piDst.PropertyType)
					{
						if (piDst.CanWrite)
						{
							// value
							object srcVal = piSrc.GetValue(entitySource, null);
							piDst.SetValue(entityDestination, srcVal, null);
						}
					}
					else
					{
						// Managing nullable values ....
					}
				}
			}
		}
	}
	return (T)entityDestination;
}

Versione compatta e realistica:

private T MapCustom<T>(object entitySource)
{
	Type entityDestType = typeof(T);
	Type entitySourceType = entitySource.GetType();
	T entityDestination = (T)entityDestType.Assembly.CreateInstance(entityDestType.FullName);
	string srcPropertyName = string.Empty;
	string csvNotMatchingPropertiesName = string.Empty; // Not used BUT may be logged for debug purpose!
 
	try
	{
		// Arrray of member static and public, nested type are not returned:
		PropertyInfo[] arrPropertyInfoDest = entityDestType.GetProperties() //BindingFlags.FlattenHierarchy
															.Where(pd => pd.CanWrite).ToArray();
 
		// For each member static and public, nested type are not returned:
		foreach (PropertyInfo piSrc in entitySourceType.GetProperties() //BindingFlags.FlattenHierarchy
															.Where(ps => ps.CanRead))
		{
			srcPropertyName = piSrc.Name;
			PropertyInfo piDst = arrPropertyInfoDest.SingleOrDefault(i => i.Name.Equals(piSrc.Name,
																			   StringComparison.InvariantCultureIgnoreCase)
																		   && i.PropertyType == piSrc.PropertyType);
			if (piDst != null)
			{
				// Set value:
				object srcVal = piSrc.GetValue(entitySource, null);
				piDst.SetValue(entityDestination, srcVal, null);
			}
			else
			{
				csvNotMatchingPropertiesName += string.Format("{0},", srcPropertyName);
			}
		}
	}
	catch (Exception ex)
	{
		priceListManager.Error(string.Format("Error on source property '{0}'.\r\n{1}", 
											srcPropertyName, ex.Message), 
								ex);
		// ToDo Manage exception!
	}
	return (T)entityDestination;
}

Mappa e Links


C# | Helper DB


Esempio completo Helper

Author