コード例 #1
0
        /// <summary>
        /// Populate or Refresh Object Relation Implementation
        /// </summary>
        /// <param name="relationBind">Element Binding for Relation Field</param>
        /// <param name="localBind">Local Binding for Value Match</param>
        /// <param name="remoteBind">Remote Binding for Column Match</param>
        /// <param name="remoteHandler">Remote Table Handler for Cache Retrieving</param>
        /// <param name="dataObjects">DataObjects to Populate</param>
        protected virtual void FillObjectRelationsImpl(ElementBinding relationBind, ElementBinding localBind, ElementBinding remoteBind, DataTableHandler remoteHandler, IEnumerable <DataObject> dataObjects)
        {
            var type          = relationBind.ValueType;
            var isElementType = false;

            if (type.HasElementType)
            {
                type          = type.GetElementType();
                isElementType = true;
            }

            var objects = dataObjects.ToArray();
            IEnumerable <IEnumerable <DataObject> > objsResults = null;

            // Handle Cache Search if relevent or use a Select Query
            if (remoteHandler.UsesPreCaching)
            {
                // Search with Primary Key or use a Where Clause
                if (remoteHandler.PrimaryKeys.All(pk => pk.ColumnName.Equals(remoteBind.ColumnName, StringComparison.OrdinalIgnoreCase)))
                {
                    objsResults = objects.Select(obj => {
                        var local = localBind.GetValue(obj);
                        if (local == null)
                        {
                            return(new DataObject[0]);
                        }

                        var retrieve = remoteHandler.GetPreCachedObject(local);
                        if (retrieve == null)
                        {
                            return(new DataObject[0]);
                        }

                        return(new [] { retrieve });
                    });
                }
                else
                {
                    objsResults = objects
                                  .Select(obj => remoteHandler.SearchPreCachedObjects(rem => {
                        var local  = localBind.GetValue(obj);
                        var remote = remoteBind.GetValue(rem);
                        if (local == null || remote == null)
                        {
                            return(false);
                        }

                        if (localBind.ValueType == typeof(string) || remoteBind.ValueType == typeof(string))
                        {
                            return(remote.ToString().Equals(local.ToString(), StringComparison.OrdinalIgnoreCase));
                        }

                        return(remote == local);
                    }));
                }
            }
            else
            {
                var whereClauses = objects.Select(obj => DB.Column(remoteBind.ColumnName).IsEqualTo(localBind.GetValue(obj)));
                objsResults = MultipleSelectObjectsImpl(remoteHandler, whereClauses);
            }

            var resultByObjs = objsResults.Select((obj, index) => new { DataObject = objects[index], Results = obj }).ToArray();

            // Store Relations
            foreach (var result in resultByObjs)
            {
                if (isElementType)
                {
                    if (result.Results.Any())
                    {
                        MethodInfo castMethod    = typeof(Enumerable).GetMethod("OfType").MakeGenericMethod(type);
                        MethodInfo methodToArray = typeof(Enumerable).GetMethod("ToArray").MakeGenericMethod(type);
                        relationBind.SetValue(result.DataObject, methodToArray.Invoke(null, new object[] { castMethod.Invoke(null, new object[] { result.Results }) }));
                    }
                    else
                    {
                        relationBind.SetValue(result.DataObject, null);
                    }
                }
                else
                {
                    relationBind.SetValue(result.DataObject, result.Results.SingleOrDefault());
                }
            }

            // Fill Sub Relations
            FillObjectRelations(resultByObjs.SelectMany(result => result.Results), false);
        }