コード例 #1
0
        /// <summary>
        /// THE REAL PROPER CHAINING ENDPOINT! Will perform ONE chain request (after linking with previous chains)
        /// </summary>
        /// <param name="data"></param>
        /// <param name="baggage"></param>
        /// <typeparam name="S"></typeparam>
        /// <typeparam name="V"></typeparam>
        /// <returns></returns>
        public async Task ChainAsync <S, V>(ChainRequest <S, V> data, List <List <IIdView> > previousChains)
            where V : IIdView where S : IConstrainedSearcher
        {
            Dictionary <string, PropertyInfo> properties = null;

            Type type = typeof(V);

            //My poor design has led to this...
            if (type == typeof(UserViewFull))
            {
                type = typeof(UserViewBasic);
            }

            var baseProperties = GetProperties(type);

            //Before doing ANYTHING, IMMEDIATELY convert fields to actual properties. It's easy if they pass us null: they want everything.
            if (data.fields == null)
            {
                properties = baseProperties.ToDictionary(x => x.Name, x => x);
            }
            else
            {
                var lowerFields = data.fields.Select(x => x.ToLower());
                properties = baseProperties.Where(x => lowerFields.Contains(x.Name.ToLower())).ToDictionary(x => x.Name, x => x);

                if (properties.Count != data.fields.Count)
                {
                    throw new BadRequestException($"Unknown fields in list: {string.Join(",", data.fields)}");
                }
            }

            //Parse the chains, get the ids. WARN: THIS IS DESTRUCTIVE TO DATA.BASESEARCH!!!
            foreach (var c in data.chains)
            {
                LinkToSearch(c, previousChains, data.baseSearch);
            }

            var myResults = await data.retriever(data.baseSearch);

            previousChains.Add(myResults.Cast <IIdView>().ToList());

            //Only add ones that aren't in the list
            foreach (var v in myResults)
            {
                if (!data.mergeList.Any(x => x.id == v.id))
                {
                    var result = new TaggedChainResult()
                    {
                        id = v.id, result = new ExpandoObject()
                    };

                    foreach (var p in properties)
                    {
                        result.result.TryAdd(p.Key, p.Value.GetValue(v));
                    }

                    lock (data.mergeLock)
                    {
                        data.mergeList.Add(result);
                    }
                }
            }
        }