Example #1
0
        public IEnumerable <XElement> GetReferencedXElements(IQueryable <SOURCE> sourceTypeIqueryable, List <string> destinationPropertyNames, XName elementName, string propertyNamePrefix)
        {
            IQueryable <DEST> data = GetReferencedQueryable(sourceTypeIqueryable);
            Expression <Func <DEST, XElement> > xelementSelector = XElementSelectHelper <DEST> .BuildXElementSelector(destinationPropertyNames, elementName, propertyNamePrefix);

            return(data.Select(xelementSelector));
        }
Example #2
0
        public static IEnumerable <XElement> GetXElements(
            Expression <Func <T, bool> > filter,
            LambdaExpression orderBy,
            bool orderAscending,
            int coreElementItemsPerPage,
            int coreElementPageNumber,
            IEnumerable <string> propertyNames,
            XNamespace elementNamespace,
            string elementNameString,
            bool showReferencesInline,
            bool showPagingInfo,
            bool randomized)
        {
            List <string> propertyNameList           = new List <string>(propertyNames);
            List <string> autoAppendedPropertyNames  = new List <string>();
            List <string> referencedIdAttrubuteNames = new List <string>();

            XName coreElementName = elementNamespace + elementNameString;

            Dictionary <string, List <string> > referencesLookup = new Dictionary <string, List <string> >();

            foreach (string referencePropertyName in propertyNameList.Where(f => f.Contains(".")))
            {
                string[] referenceElements = referencePropertyName.Split('.');
                if (referenceElements.Length != 2)
                {
                    throw new InvalidOperationException(string.Format("Property names with a dot must have exactly one dot - failed to parse '{0}'", referencePropertyName));
                }

                if (referencesLookup.ContainsKey(referenceElements[0]) == false)
                {
                    referencesLookup.Add(referenceElements[0], new List <string>());
                }

                referencesLookup[referenceElements[0]].Add(referenceElements[1]);
            }

            // rewrite with linq
            if (showReferencesInline)
            {
                // Ensure keys are included
                foreach (string referencePropertyName in referencesLookup.Keys)
                {
                    if (propertyNameList.Contains(referencePropertyName) == false)
                    {
                        propertyNameList.Add(referencePropertyName);
                        autoAppendedPropertyNames.Add(referencePropertyName);
                    }
                }
            }


            var result = new List <XElement>();

            Expression <Func <T, XElement> > xelementSelector = XElementSelectHelper <T> .BuildXElementSelector(propertyNameList.Where(f => f.IndexOf('.') == -1).ToList(), coreElementName);

            // TODO: handle case of the default sorting (by predicate element => true)
            IOrderByTypeFixer <T> orderByTypeFixer = GetOrderByTypeFixer(orderBy);
            IQueryable <T>        coreDataItems    = orderByTypeFixer.GetCastedIQueryable(filter, orderBy, orderAscending, coreElementItemsPerPage, coreElementPageNumber, randomized);

            if (randomized && referencesLookup.Any())
            {
                // performance hit! make elegant when time permits.
                coreDataItems = coreDataItems.ToList().AsQueryable();
            }

            // Perf. optimization
            if (coreDataItems.IsEnumerableQuery())
            {
                Func <T, XElement> compiledExpression = XElementSelectHelper <T> .GetCompiledFunction(xelementSelector);

                result.AddRange(Enumerable.Select(coreDataItems, compiledExpression));
            }
            else
            {
                result.AddRange(coreDataItems.Select(xelementSelector));
            }

            var referencedResults = new List <XElement>();

            // int referencedCoreElementCount = (orderByIsDeterministic ? coreElementItemsPerPage : int.MaxValue);
            foreach (string referencePropertyName in referencesLookup.Keys)
            {
                IReferencedDataHelper <T> fixer = ReferencedDataHelperBuilder <T> .Build(referencePropertyName);

                string propertyNamePrefix = (showReferencesInline ? referencePropertyName + "." : "");
                if (showReferencesInline)
                {
                    if (referencesLookup[referencePropertyName].Contains(fixer.TargetTypeKeyPropertyName) == false)
                    {
                        referencesLookup[referencePropertyName].Add(fixer.TargetTypeKeyPropertyName);
                        autoAppendedPropertyNames.Add(propertyNamePrefix + fixer.TargetTypeKeyPropertyName);
                    }
                    referencedIdAttrubuteNames.Add(propertyNamePrefix + fixer.TargetTypeKeyPropertyName);
                }
                XName referenceElementName           = elementNamespace + referencePropertyName;
                IEnumerable <XElement> referencesXml = fixer.GetReferencedXElements(coreDataItems, referencesLookup[referencePropertyName], referenceElementName, propertyNamePrefix);
                referencedResults.AddRange(referencesXml);
            }

            if (showReferencesInline)
            {
                Dictionary <string, IEnumerable <XElement> >    referencedElementsLookup       = new Dictionary <string, IEnumerable <XElement> >();
                Dictionary <string, Func <string, XAttribute> > referencedElementLocatorLookup = new Dictionary <string, Func <string, XAttribute> >();

                foreach (string referencePropertyName in referencesLookup.Keys)
                {
                    XName referenceElementName = elementNamespace + referencePropertyName;

                    IEnumerable <XElement> referenceElements = referencedResults.Where(f => f.Name == referenceElementName);
                    referencedElementsLookup.Add(referencePropertyName, referenceElements);

                    string idPropertyName = referencedIdAttrubuteNames.First(g => g.StartsWith(referencePropertyName + "."));
                    IEnumerable <XElement>    referencedElements = referencedElementsLookup[referencePropertyName];
                    Func <string, XAttribute> locateByKeyFunc    = f => referencedElements.Attributes(idPropertyName).FirstOrDefault(g => g.Value == f);
                    referencedElementLocatorLookup.Add(referencePropertyName, locateByKeyFunc);
                }

                foreach (XElement coreElement in result.Where(f => f.Name == coreElementName))
                {
                    foreach (string referencePropertyName in referencesLookup.Keys)
                    {
                        XAttribute referenceAttribute = coreElement.Attribute(referencePropertyName);
                        if (referenceAttribute == null)
                        {
                            continue;                             // Handles non-references
                        }
                        string keyValue = referenceAttribute.Value;
                        Func <string, XAttribute> fetcher = referencedElementLocatorLookup[referencePropertyName];
                        XAttribute matchingKeyAttribute   = fetcher(keyValue);
                        if (matchingKeyAttribute != null)
                        {
                            XElement referenced = matchingKeyAttribute.Parent;
                            coreElement.Add(referenced.Attributes());
                        }
                    }

                    coreElement.Attributes().Where(f => autoAppendedPropertyNames.Contains(f.Name.LocalName)).Remove();

                    yield return(coreElement);
                }
            }
            else
            {
                foreach (XElement anyElement in result)
                {
                    yield return(anyElement);
                }

                foreach (XElement anyElement in referencedResults)
                {
                    yield return(anyElement);
                }
            }

            if (showPagingInfo)
            {
                int totalItemCount          = DataFacade.GetData <T>(filter).Count(); // TODO: there shoudn't be a query
                int firstShownElementNumber = ((coreElementPageNumber - 1) * coreElementItemsPerPage) + 1;
                int lastShownElementNumber  = Math.Min(totalItemCount, firstShownElementNumber + (coreElementItemsPerPage - 1));
                int shownItemsCount         = Math.Max(0, (lastShownElementNumber - firstShownElementNumber) + 1);

                int totelPageCount = (int)Math.Ceiling((((double)totalItemCount) / ((double)coreElementItemsPerPage)));

                XElement pagingInfo = new XElement(elementNamespace + "PagingInfo",
                                                   new XAttribute("CurrentPageNumber", coreElementPageNumber),
                                                   new XAttribute("TotalPageCount", totelPageCount),
                                                   new XAttribute("TotalItemCount", totalItemCount),
                                                   new XAttribute("ShownItemsCount", shownItemsCount),
                                                   new XAttribute("MaximumItemsPerPage", coreElementItemsPerPage)
                                                   );

                if (shownItemsCount > 0)
                {
                    pagingInfo.Add(
                        new XAttribute("CurrentItemNumberStart", firstShownElementNumber),
                        new XAttribute("CurrentItemNumberEnd", lastShownElementNumber)
                        );
                }

                yield return(pagingInfo);
            }
        }