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