public async Task SetValueAsync(IDeferredItem <TItem> item, object deserializedValue, IDataTransaction dataTransaction)
        {
            object loadedValue;

            try
            {
                ForEachAsyncDelegate <object> forEachAsync = ItemQueryHelper.DefaultForEachAsync; // TODO get from item?
                loadedValue = await ScalarFieldHelper.LoadScalarValueAsync(_fieldReader, item.Query, forEachAsync);
            }
            catch (Exception ex)
            {
                throw new ConfirmOnlyValueLoadException(ex, deserializedValue);
            }

            // TODO find a more efficient way. Possibly generic values too?

            if (loadedValue.Equals(deserializedValue))
            {
                return;
            }

            if (_fieldReader.FieldType.IsEnum)
            {
                loadedValue = Convert.ToInt64(loadedValue);
            }

            if (loadedValue.ToString() == deserializedValue.ToString())
            {
                return;
            }

            throw new InvalidOperationException("Cannot set the '" + _fieldName + "' field. Given value must be equal to the current value.");
        }
Esempio n. 2
0
        public static async Task <T> SingleOrCreateAsync <T>(IQueryable <T> source, ForEachAsyncDelegate <T> forEachAsync, Func <T> createItemFunc)
            where T : class
        {
            IQueryable <T> takeQuery = source.Take(2);

            T   returnObj = null;
            int i         = 0;

            await forEachAsync(takeQuery, item =>
            {
                if (++i > 1)
                {
                    throw new MultipleItemsMatchedReferenceException();
                }

                returnObj = item;
            });

            if (i == 0)
            {
                return(createItemFunc());
            }

            return(returnObj);
        }
Esempio n. 3
0
        public static Task <object> SingleOrCreateAsync(IQueryable source, ForEachAsyncDelegate <object> forEachAsync, Func <object> createItemFunc)
        {
            if (source.IsInMemory()) // nasty fix for non-entity queries.
            {
                return(SingleOrCreateAsync(source.OfType <object>(), forEachAsync, createItemFunc));
            }

            if (source.ElementType.IsValueType) // executes the query here. works around that EF can't box value types.
            {
                return(Task.FromResult(SingleOrCreate(IterateObjects(source), createItemFunc)));
            }

            return(SingleOrCreateAsync(source.AsObjects(), forEachAsync, createItemFunc));
        }
        /// <summary>
        /// Executes a query that selects only the desired fields from an <see cref="IQueryable{TItem}"/>.
        /// </summary>
        public async Task <QueriedDataIterator> SelectFieldsOnlyAsync(IQueryable <TItem> items, ForEachAsyncDelegate <object> forEachAsync)
        {
            Type       dynamicType      = GetDynamicRuntimeType();
            IQueryable dynamicQueryable = GetDynamicQueryable(items, dynamicType);

            var replacementProcessor = new FieldReplacementProcessor <TItem>(_fieldReaders);
            await replacementProcessor.LoadAllAsync(items);

            List <object> dynamicObjects = await ExecuteWithReplacementsAsync(replacementProcessor, dynamicQueryable, forEachAsync);

            return(new QueriedDataIterator(dynamicObjects));
        }
        private static async Task <List <object> > ExecuteWithReplacementsAsync(FieldReplacementProcessor <TItem> replacementProcessor, IQueryable dynamicQueryable, ForEachAsyncDelegate <object> forEachAsync)
        {
            var dynamicType   = dynamicQueryable.ElementType;
            var returnObjects = new List <object>();

            if (dynamicQueryable.IsInMemory())
            {
                await ItemQueryHelper.DefaultForEachAsync(dynamicQueryable, AddObjectToList);
            }
            else
            {
                await forEachAsync(dynamicQueryable.AsObjects(), AddObjectToList);
            }

            void AddObjectToList(object dynamicObj)
            {
                if (dynamicObj != null)
                {
                    replacementProcessor.Replace(dynamicObj, dynamicType);
                }

                returnObjects.Add(dynamicObj);
            }

            return(returnObjects);
        }
Esempio n. 6
0
 public static Task <T> SingleOrThrowAsync <T>(IQueryable <T> source, ForEachAsyncDelegate <T> forEachAsync)
     where T : class
 {
     return(SingleOrCreateAsync(source, forEachAsync, ThrowNotFound <T>));
 }
        /// <summary>
        /// Loads a single scalar field reader from a single <see cref="itemQuery"/>.
        /// </summary>
        public static async Task <object> LoadScalarValueAsync <TItem>([NotNull] IFieldReader <TItem> reader, IQueryableSingle <TItem> itemQuery, ForEachAsyncDelegate <object> forEachAsync)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            ParameterExpression itemPram         = Expression.Parameter(typeof(TItem), "itm");
            Expression          selectExpression = reader.GetSelectExpression(itemPram);

            IQueryable selectScalarOnlyQuery = ExpressionTreeHelpers.GetSelectExpressionQuery(itemQuery, itemPram, selectExpression);
            object     loadedValue           = await ItemQueryHelper.SingleOrCreateAsync(selectScalarOnlyQuery, forEachAsync, () => throw new ParentItemNotFoundException());

            if (reader.Replacer != null)
            {
                await reader.Replacer.LoadAsync(itemQuery);

                return(reader.Replacer.GetReplacement(loadedValue));
            }

            return(loadedValue);
        }