예제 #1
0
        public static ODataMetadata Build(ODataExpression oDataExpression, MetadataBase guideMetadata, MetadataBase complementaryMetadata)
        {
            ODataMetadata instance = new ODataMetadata();

            // OrderBy
            List <OrderBy> ambiguousOrdersBy = new List <OrderBy>();

            foreach (OrderBy orderBy in oDataExpression.OrdersBy)
            {
                if (guideMetadata.GetProperty(orderBy.PropertyName) != null && complementaryMetadata.GetProperty(orderBy.PropertyName) != null)
                {
                    ambiguousOrdersBy.Add(orderBy);
                }
                else if (guideMetadata.GetProperty(orderBy.PropertyName) != null)
                {
                    instance.ordersByMetadata.Add(orderBy, guideMetadata);
                }
                else if (complementaryMetadata.GetProperty(orderBy.PropertyName) != null)
                {
                    instance.ordersByMetadata.Add(orderBy, complementaryMetadata);
                }
                else
                {
                    throw new Exception($"The property {orderBy.PropertyName} does not exists on {guideMetadata.UnderlyingType.FullName} or {complementaryMetadata.UnderlyingType.FullName}. Metadata orderBy");
                }
            }

            if (ambiguousOrdersBy.Any())
            {
                int differentOrderBySources = instance.ordersByMetadata.Values.Distinct().Count();
                if (differentOrderBySources > 1)
                {
                    throw new Exception($"OrderBy clauses only can be apply over one query");
                }
                else if (differentOrderBySources == 1) // Solo hay un origen, debe ser el mismo para todos
                {
                    // Se vuelcan los ambiguos
                    MetadataBase metadataBase = instance.ordersByMetadata.Values.First();
                    ambiguousOrdersBy.ForEach(o => instance.ordersByMetadata.Add(o, metadataBase));
                    ambiguousOrdersBy.Clear();
                }
            }

            // Filters
            List <FilterBase> ambiguousFilters = new List <FilterBase>();

            foreach (FilterBase filter in oDataExpression.GetAllFilters())
            {
                if (guideMetadata.GetProperty(filter.PropertyName) != null && complementaryMetadata.GetProperty(filter.PropertyName) != null)
                {
                    ambiguousFilters.Add(filter);
                }
                else if (guideMetadata.GetProperty(filter.PropertyName) != null)
                {
                    instance.filtersMetadata.Add(filter, guideMetadata);
                }
                else if (complementaryMetadata.GetProperty(filter.PropertyName) != null)
                {
                    instance.filtersMetadata.Add(filter, complementaryMetadata);
                }
                else
                {
                    throw new Exception($"The property {filter.PropertyName} does not exists on {guideMetadata.UnderlyingType.FullName} or {complementaryMetadata.UnderlyingType.FullName}. Metadata filter");
                }
            }

            // Resolución final de ambiguos
            if (ambiguousFilters.Any())
            {
                MetadataBase filterMetadata = instance.filtersMetadata.Values.FirstOrDefault();
                if (filterMetadata != null)
                {
                    // Todos van al primero de los origenes de los filtros
                    ambiguousFilters.ForEach(f => instance.filtersMetadata.Add(f, filterMetadata));
                }
                else
                {
                    // No hay, ¿y order by?
                    if (instance.ordersByMetadata.Any())
                    {
                        // Todos al mismo que el/los orderby
                        ambiguousFilters.ForEach(f => instance.filtersMetadata.Add(f, instance.ordersByMetadata.Values.First()));
                    }
                    else
                    {
                        // Hardcode a la guia. No hay criterio para elegir
                        ambiguousFilters.ForEach(f => instance.filtersMetadata.Add(f, guideMetadata));
                    }
                }
            }

            if (ambiguousOrdersBy.Any())
            {
                // No hay orders by no ambiguos, se coge como referencia los filtros
                MetadataBase filterMetadata = instance.filtersMetadata.Values.FirstOrDefault();
                if (filterMetadata != null)
                {
                    // Al primero de los filtros
                    ambiguousOrdersBy.ForEach(o => instance.ordersByMetadata.Add(o, filterMetadata));
                }
                else
                {
                    // Sin mucho criterio para elegir: a la guia
                    ambiguousOrdersBy.ForEach(o => instance.ordersByMetadata.Add(o, guideMetadata));
                }
            }

            return(instance);
        }