public void ProcessQueue(MereCataloger p, bool recursiveLoad) { //once the raw results have been processed, connect all the related objects while (queue.Count > 0) { InstantiateAssociated(p, queue.Dequeue(), recursiveLoad); } }
/// <summary> /// Go through an item's "associated" properties and attempt to find in this ResultSet. Potentially load from the MereCataloger if missing /// </summary> /// <param name="p">The MereCataloger to attempt to load from if required</param> /// <param name="item">the item that is being parsed and "associated"</param> /// <param name="recursiveLoad">Dictates whether to manually attempt to load missing results expected during wiring up the "associated properties</param> private void InstantiateAssociated(MereCataloger p, object item, bool recursiveLoad) { Catalogable t = Catalogable.For(item); object itemID = t.ID(item); foreach (PropertyInfo property in t.Associated) { TypeEx tEx = property.TypeEx(); if (property.GetValue(item, null) != null) { continue; } Catalogable pt = Catalogable.For(tEx.ElementType); if (tEx.IsListOrArray) { object[] result = null; string KeyID = t.HasPropertyAttribute(property) ? t.PropertyAttribute(property).KeyID : t.Reference; if (pt.Cached && pt.Cache != null) { result = pt.Cache.Where(obj => pt.ColumnValue(obj, KeyID).Equals(itemID)).ToArray(); } else { //if in the results then use, else load in using Find method on the relatedBusinessObject if (result == null && results.ContainsKey(tEx.ElementType.FullName)) { result = results[tEx.ElementType.FullName] .Select(obj => Convert.ChangeType(obj.Value, tEx.ElementType)) //is this needed? at the very least, can it be moved to after the where .Where(obj => pt.ColumnValue(obj, KeyID).Equals(itemID)).ToArray(); } //if none found but recursiveLoad is allowed, manually get the results if ((result == null || ((IList)result).Count == 0) && recursiveLoad) { result = (object[])p._FindMethod(tEx.ElementType).Invoke(p, new object[] { false, false, new object[] { KeyID, itemID } }); Add(result); } } if (result != null) { if (tEx.IsArray) { Array array = Array.CreateInstance(tEx.ElementType, result.Count()); Array.Copy(result, array, result.Length); property.SetValue(item, array, null); } else { IList list = (IList)Activator.CreateInstance(property.PropertyType); foreach (object o in (object[])result) { list.Add(o); } property.SetValue(item, list, null); } } } else //singular objects { object result = null; if (pt.IDProperty == null) //possibly because it's not been "excluded" { continue; } string KeyID = t.HasPropertyAttribute(property) ? t.PropertyAttribute(property).KeyID : pt.Reference; object id = t.ColumnValue(item, KeyID); //if in the results then use, else load in using Find method on the relatedBusinessObject if (pt.Cached && pt.Cache != null) { result = pt.Cache.FirstOrDefault(o => pt.ID(o).Equals(id)); } else //if (result == null) { { if (results.ContainsKey(property.PropertyType.FullName) && results[property.PropertyType.FullName].ContainsKey(id)) { result = results[property.PropertyType.FullName][id]; } else if (recursiveLoad) //if none found but recursiveLoad is allowed, manually get the results //if ((long)id != 0) { { if (id != null) { result = p._FindByIDMethod(property.PropertyType).Invoke(p, new object[] { false, false, id }); Add(result); } } } if (result != null) { property.SetValue(item, result, null); } } } }