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); }