/// <summary> /// Initializes a new instance of the <see cref="UpdateEntryDto"/> class. /// </summary> /// <param name="entry">The state entry of an entity.</param> /// <param name="mapper">The <see cref="IDynamicObjectMapper" /> used for mapping the property values.</param> public UpdateEntryDto(IUpdateEntry entry, IDynamicObjectMapper mapper) { DynamicObject CreateValueDto(IProperty propertyBase, object value) { value = Utils.ConvertToProvider(value, propertyBase); return(mapper.MapObject(value)); } this.EntityTypeName = entry.EntityType.DisplayName(); this.EntityState = entry.EntityState; this.PropertyDatas = entry.ToEntityEntry().Properties.Select( prop => new PropertyData { Name = prop.Metadata.Name, OriginalValueDto = prop.Metadata.GetOriginalValueIndex() >= 0 ? CreateValueDto(prop.Metadata, prop.OriginalValue) : null, CurrentValueDto = CreateValueDto(prop.Metadata, prop.CurrentValue), IsModified = prop.IsModified, IsTemporary = prop.IsTemporary, }).ToList(); if (entry.EntityType.HasDefiningNavigation()) { var ownership = entry.EntityType.GetForeignKeys().Single(fk => fk.IsOwnership); this.DelegatedIdentityDatas = ownership.Properties.Select( prop => new PropertyData { Name = prop.Name, OriginalValueDto = CreateValueDto(prop, entry.GetOriginalValue(prop)), CurrentValueDto = CreateValueDto(prop, entry.GetCurrentValue(prop)), IsModified = entry.IsModified(prop), IsTemporary = entry.HasTemporaryValue(prop), }).ToList(); } }
/// <summary> /// Initializes a new instance of the <see cref="DefaultExpressionExecutor"/> class. /// </summary> public DefaultExpressionExecutor(Func <Type, IQueryable> queryableProvider, IExpressionFromRemoteLinqContext?context = null, Func <Type, bool>?setTypeInformation = null) : base(queryableProvider, context) { _mapper = (context ?? ExpressionTranslatorContext.Default).ValueMapper ?? throw new ArgumentException($"{nameof(IExpressionValueMapperProvider.ValueMapper)} property must not be null.", nameof(context)); _setTypeInformation = setTypeInformation ?? (t => !t.IsAnonymousType()); }
/// <summary> /// Initializes a new instance of the <see cref="ExpressionExecutor"/> class. /// </summary> public ExpressionExecutor(Func <Type, IQueryable> queryableProvider, ITypeResolver typeResolver = null, IDynamicObjectMapper mapper = null, Func <Type, bool> setTypeInformation = null, Func <System.Linq.Expressions.Expression, bool> canBeEvaluatedLocally = null) { _queryableProvider = queryableProvider; _typeResolver = typeResolver; _mapper = mapper ?? new DynamicQueryResultMapper(); _setTypeInformation = setTypeInformation ?? (t => !t.IsAnonymousType()); _canBeEvaluatedLocally = canBeEvaluatedLocally; }
public DefaultEntityFrameworkExpressionExecutor( Func <Type, IQueryable> queryableProvider, IExpressionTranslatorContext?context = null, Func <Type, bool>?setTypeInformation = null) : base(queryableProvider, context ??= new EntityFrameworkExpressionTranslatorContext()) { _mapper = context.ValueMapper; _setTypeInformation = setTypeInformation ?? (t => !t.IsAnonymousType()); }
/// <summary> /// Returns the current values of scalar properties of the entity. /// </summary> /// <param name="entityType">The type of the entity.</param> /// <param name="mapper">The <see cref="IDynamicObjectMapper" /> used for mapping the property values.</param> /// <returns> /// The current values of scalar properties of the entity mapped back to their original types. /// </returns> public object[] GetCurrentValues(IEntityType entityType, IDynamicObjectMapper mapper) { return(entityType .GetProperties() .Select(p => Utils.ConvertFromProvider( mapper.Map(this.PropertyDatas.SingleOrDefault(pd => pd.Name == p.Name)?.CurrentValueDto), p)) .ToArray()); }
public DefaultReactiveAsyncStreamExpressionExecutor( Func <Type, IAsyncQueryable> queryableProvider, IExpressionFromRemoteLinqContext?context = null, Func <Type, bool>?setTypeInformation = null) : base(queryableProvider, context ??= new AsyncQueryExpressionTranslatorContext()) { _mapper = context.ValueMapper; _setTypeInformation = setTypeInformation ?? (t => !t.IsAnonymousType()); }
/// <summary> /// Matches the <see cref="PropertyEntry" />'s of the given <see cref="EntityEntry" /> with corresponding <see cref="PropertyData"/>'s. /// </summary> /// <param name="entry">The reference <see cref="EntityEntry" />.</param> /// <param name="mapper">The <see cref="IDynamicObjectMapper" /> used for mapping the property values.</param> /// <returns> /// The list of matching scalar properties alongside their Origianl and Current values /// mapped back to their original types. /// </returns> public IReadOnlyList <(PropertyEntry EfProperty, PropertyData DtoProperty, object OriginalValue, object CurrentValue)> JoinScalarProperties( EntityEntry entry, IDynamicObjectMapper mapper) { return(( from ef in entry.Properties join dto in this.PropertyDatas on ef.Metadata.Name equals dto.Name select(ef, dto, Utils.ConvertFromProvider(mapper.Map(dto.OriginalValueDto), ef.Metadata), Utils.ConvertFromProvider(mapper.Map(dto.CurrentValueDto), ef.Metadata))).ToList()); }
/// <summary> /// Initializes a new instance of the <see cref="DynamicObject"/> class, /// representing the object structure defined by the specified object. /// </summary> /// <param name="obj">The object to be represented by the new dynamic object.</param> /// <param name="mapper">Optional instance of dynamic object mapper.</param> /// <exception cref="ArgumentNullException">The specified object is null.</exception> public DynamicObject(object obj, IDynamicObjectMapper mapper = null) { if (obj is null) { throw new ArgumentNullException(nameof(obj)); } var dynamicObject = (mapper ?? new DynamicObjectMapper()).MapObject(obj); Type = dynamicObject.Type; Properties = dynamicObject.Properties; }
public RemoteToSystemLinqTranslator(IExpressionFromRemoteLinqContext expressionTranslatorContext) { expressionTranslatorContext.AssertNotNull(nameof(expressionTranslatorContext)); _parameterExpressionCache = new Dictionary <RemoteLinq.ParameterExpression, SystemLinq.ParameterExpression>(ExpressionComparer.Default); _labelTargetCache = new Dictionary <RemoteLinq.LabelTarget, SystemLinq.LabelTarget>(ExpressionComparer.Default); _typeResolver = expressionTranslatorContext.TypeResolver ?? throw new ArgumentException($"{nameof(expressionTranslatorContext.TypeResolver)} property must not be null.", nameof(expressionTranslatorContext)); _dynamicObjectMapper = expressionTranslatorContext.ValueMapper ?? throw new ArgumentException($"{nameof(expressionTranslatorContext.ValueMapper)} property must not be null.", nameof(expressionTranslatorContext)); }
public SystemToRemoteLinqTranslator(IExpressionToRemoteLinqContext expressionTranslatorContext) { expressionTranslatorContext.AssertNotNull(nameof(expressionTranslatorContext)); _canBeEvaluatedLocally = expressionTranslatorContext.CanBeEvaluatedLocally; _needsMapping = expressionTranslatorContext.NeedsMapping; _typeInfoProvider = expressionTranslatorContext.TypeInfoProvider ?? throw new ArgumentException($"{nameof(expressionTranslatorContext.TypeInfoProvider)} property must not be null.", nameof(expressionTranslatorContext)); _dynamicObjectMapper = expressionTranslatorContext.ValueMapper ?? throw new ArgumentException($"{nameof(expressionTranslatorContext.ValueMapper)} property must not be null.", nameof(expressionTranslatorContext)); }
internal static T MapToType <T>(IEnumerable <DynamicObject> dataRecords, IDynamicObjectMapper mapper, Expression expression) { var elementType = TypeHelper.GetElementType(typeof(T)); if (mapper is null) { mapper = new DynamicQueryResultMapper(); } var result = mapper.Map(dataRecords, elementType); if (result is null) { return(default);
internal static T MapToType <T>(IEnumerable <DynamicObject> dataRecords, IDynamicObjectMapper mapper, Expression expression) { var elementType = TypeHelper.GetElementType(typeof(T)); var strElementType = elementType.Name; if (mapper is null) { mapper = new DynamicQueryResultMapper(); } var result = mapper.Map(dataRecords, elementType); if (result is null) { return(default(T)); } if (typeof(T).IsAssignableFrom(typeof(IEnumerable <>).MakeGenericType(elementType))) { return((T)result); } if (typeof(T).IsAssignableFrom(elementType)) { try { object single; if ((expression as MethodCallExpression)?.Arguments.Count == 2) { var predicate = GetTruePredicate(elementType); single = MethodInfos.Enumerable.SingleWithFilter.MakeGenericMethod(elementType).Invoke(null, new object[] { result, predicate }); } else { single = MethodInfos.Enumerable.Single.MakeGenericMethod(elementType).Invoke(null, new object[] { result }); } return((T)single); } catch (TargetInvocationException ex) { throw ex.InnerException; } } throw new Exception(string.Format("Failed to cast result of type '{0}' to '{1}'", result.GetType(), typeof(T))); }
/// <summary> /// Maps a collection of <see cref="DynamicObject" />s into a collection of objects. /// </summary> /// <param name="objectMapper">The <see cref="IDynamicObjectMapper"/> instance used to map the <see cref="DynamicObject"/>s.</param> /// <param name="objects">Collection of <see cref="DynamicObject" /> to be mapped.</param> /// <param name="type">Target type for mapping, set this parameter to <see langword="null"/> if type information included within individual <see cref="DynamicObject" />s should be used.</param> /// <returns>Collection of objects created based on the <see cref="DynamicObject" />s specified.</returns> public static IEnumerable Map(this IDynamicObjectMapper objectMapper, IEnumerable <DynamicObject?> objects, Type?type = null) { if (objectMapper is null) { throw new ArgumentNullException(nameof(objectMapper)); } if (objects is null) { throw new ArgumentNullException(nameof(objects)); } IEnumerable <object?> source = objects.Select(x => objectMapper.Map(x, type)); return(type is null || type == typeof(object) ? source.ToArray() : source.CastCollectionToArrayOfType(type)); }
public RemoteRepository(string uri) { _mapper = new DynamicObjectMapper(isKnownTypeProvider: new IsKnownTypeProvider()); var binding = new NetNamedPipeBinding { MaxReceivedMessageSize = 10240 }.WithDebugSetting(); _channelFactory = new ChannelFactory <IQueryService>(binding, uri); _dataProvider = expression => { using var proxy = _channelFactory.CreateServiceProxy(); IEnumerable <DynamicObject> result = proxy.Service.ExecuteQuery(expression); return(result); }; }
public RemoteRepository(string uri) { _mapper = new DynamicObjectMapper(isKnownTypeProvider: new IsKnownTypeProvider()); var binding = new NetNamedPipeBinding() { CloseTimeout = TimeSpan.FromMinutes(10), ReceiveTimeout = TimeSpan.FromMinutes(10), SendTimeout = TimeSpan.FromMinutes(10), MaxReceivedMessageSize = 640000L }; _channelFactory = new ChannelFactory <IQueryService>(binding, uri); _dataProvider = expression => { IQueryService channel = null; try { channel = _channelFactory.CreateChannel(); var result = channel.ExecuteQuery(expression); return(result); } finally { var communicationObject = channel as ICommunicationObject; if (communicationObject != null) { if (communicationObject.State == CommunicationState.Faulted) { communicationObject.Abort(); } else { communicationObject.Close(); } } } }; }
public static IEnumerable <DynamicObject> ConvertResultToDynamicObjects(object queryResult, IDynamicObjectMapper mapper = null, Func <Type, bool> setTypeInformation = null) { var exec = (IExpressionExecutionDecorator) new ExpressionExecutor(null, null, mapper, setTypeInformation); return(exec.ProcessResult(exec.ConvertResult(queryResult))); }
public static ExpressionExecutionContext Executor(this Expression expression, Func <Type, IQueryable> queryableProvider, ITypeResolver typeResolver = null, IDynamicObjectMapper mapper = null, Func <Type, bool> setTypeInformation = null, Func <System.Linq.Expressions.Expression, bool> canBeEvaluatedLocally = null) => new ExpressionExecutionContext(CreateExecutor(queryableProvider, typeResolver, mapper, setTypeInformation, canBeEvaluatedLocally), expression);
public static IEnumerable <DynamicObject> Execute(this Expression expression, Func <Type, IQueryable> queryableProvider, ITypeResolver typeResolver, Func <object, object> resultProjector, IDynamicObjectMapper mapper = null, Func <Type, bool> setTypeInformation = null, Func <System.Linq.Expressions.Expression, bool> canBeEvaluatedLocally = null) => Executor(expression, queryableProvider, typeResolver, mapper, setTypeInformation, canBeEvaluatedLocally).With(resultProjector).Execute();
public DefaultEntityFrameworkExpressionExecutor(Func <Type, IQueryable> queryableProvider, ITypeResolver?typeResolver = null, IDynamicObjectMapper?mapper = null, Func <Type, bool>?setTypeInformation = null, Func <System.Linq.Expressions.Expression, bool>?canBeEvaluatedLocally = null) : base(queryableProvider, typeResolver, canBeEvaluatedLocally) { _mapper = mapper ?? new DynamicQueryResultMapper(); _setTypeInformation = setTypeInformation ?? (t => !t.IsAnonymousType()); }
private static ExpressionExecutor CreateExecutor(Func <Type, IQueryable> queryableProvider, ITypeResolver typeResolver, IDynamicObjectMapper mapper, Func <Type, bool> setTypeInformation, Func <System.Linq.Expressions.Expression, bool> canBeEvaluatedLocally) => new ExpressionExecutor(queryableProvider, typeResolver, mapper, setTypeInformation);
public EntityFrameworkExpressionExecutor(Func<Type, IQueryable> queryableProvider, ITypeResolver typeResolver = null, IDynamicObjectMapper mapper = null, Func<Type, bool> setTypeInformation = null, Func<System.Linq.Expressions.Expression, bool> canBeEvaluatedLocally = null) : base(queryableProvider, typeResolver, mapper, setTypeInformation, canBeEvaluatedLocally) { }
public DynamicResultMapper(IDynamicObjectMapper mapper) { _mapper = mapper; }
/// <summary> /// Composes and executes the query based on the <see cref="Expression"/> and mappes the result into dynamic objects. /// </summary> /// <param name="expression">The <see cref="Expression"/> to be executed.</param> /// <param name="queryableProvider">Delegate to provide <see cref="IQueryable"/> instances for given <see cref="Type"/>s.</param> /// <param name="typeResolver">Optional instance of <see cref="ITypeResolver"/> to be used to translate <see cref="Aqua.TypeSystem.TypeInfo"/> into <see cref="Type"/> objects.</param> /// <param name="mapper">Optional instance of <see cref="IDynamicObjectMapper"/>.</param> /// <param name="setTypeInformation">Function to define whether to add type information.</param> /// <param name="canBeEvaluatedLocally">Function to define which expressions may be evaluated locally, and which need to be retained for execution in the database.</param> /// <returns>The mapped result of the query execution.</returns> public static IEnumerable <DynamicObject> ExecuteWithEntityFrameworkCore(this Expression expression, Func <Type, IQueryable> queryableProvider, ITypeResolver typeResolver = null, IDynamicObjectMapper mapper = null, Func <Type, bool> setTypeInformation = null, Func <System.Linq.Expressions.Expression, bool> canBeEvaluatedLocally = null) => new EntityFrameworkCoreExpressionExecutor(queryableProvider, typeResolver, mapper, setTypeInformation, canBeEvaluatedLocally).Execute(expression);
public static IQueryable <T> CreateEntityFrameworkCoreAsyncQueryable <T>(this RemoteQueryableFactory factory, Func <Expressions.Expression, Task <IEnumerable <DynamicObject> > > dataProvider, ITypeInfoProvider typeInfoProvider = null, IDynamicObjectMapper mapper = null, Func <System.Linq.Expressions.Expression, bool> canBeEvaluatedLocally = null) => factory.CreateQueryable <T>(dataProvider, typeInfoProvider, mapper, canBeEvaluatedLocally.And(ExpressionEvaluator.CanBeEvaluated));
/// <summary> /// Creates an <see cref="ExpressionExecutionContext" /> for the given <see cref="Expression"/> /// </summary> /// <param name="expression">The <see cref="Expression"/> to be executed</param> /// <param name="queryableProvider">Delegate to provide <see cref="IQueryable"/> instances for given <see cref="Type"/>s</param> /// <param name="typeResolver">Optional instance of <see cref="ITypeResolver"/> to be used to translate <see cref="Aqua.TypeSystem.TypeInfo"/> into <see cref="Type"/> objects</param> /// <param name="mapper">Optional instance of <see cref="IDynamicObjectMapper"/></param> /// <param name="setTypeInformation">Function to define whether to add type information</param> /// <returns>A new instance <see cref="ExpressionExecutionContext" /></returns> public static ExpressionExecutionContext EntityFrameworkExecutor(this Expression expression, Func <Type, IQueryable> queryableProvider, ITypeResolver typeResolver = null, IDynamicObjectMapper mapper = null, Func <Type, bool> setTypeInformation = null) => new ExpressionExecutionContext(new EntityFrameworkExpressionExecutor(queryableProvider, typeResolver, mapper, setTypeInformation), expression);
/// <summary> /// Creates an instance of <see cref="IQueryable{T}" /> that utilizes the data provider specified. /// </summary> /// <typeparam name="T">Element type of the <see cref="IQueryable{T}"/>.</typeparam> public static IQueryable <T> CreateQueryable <T>(this RemoteQueryableFactory factory, Func <Expressions.Expression, IEnumerable <DynamicObject> > dataProvider, ITypeInfoProvider typeInfoProvider = null, IDynamicObjectMapper mapper = null, Func <System.Linq.Expressions.Expression, bool> canBeEvaluatedLocally = null) { var resultMapper = new DynamicResultMapper(mapper); return(factory.CreateQueryable <T, IEnumerable <DynamicObject> >(dataProvider, resultMapper, typeInfoProvider, canBeEvaluatedLocally)); }
/// <summary> /// Returns the values of the delegated identity key of the entity /// (for owned entities only). /// </summary> /// <param name="mapper">The <see cref="IDynamicObjectMapper" /> used for mapping the key values.</param> /// <param name="key"> The primary key of the defining entity. </param> /// <returns> /// The values of the delegated identity key of the entity mapped back to their original types. /// </returns> public object[] GetDelegatedIdentityKeys(IDynamicObjectMapper mapper, IKey key) { return(this.DelegatedIdentityDatas.Zip( key.Properties, (d, p) => Utils.ConvertFromProvider(mapper.Map(d.CurrentValueDto), p)).ToArray()); }
public DynamicObjectWithOriginalReference(object obj, IDynamicObjectMapper mapper = null) : base(obj, mapper) { _originalObject = obj; }
/// <summary> /// Composes and executes the query based on the <see cref="Expression"/> and mappes the result into dynamic objects /// </summary> /// <param name="expression">The <see cref="Expression"/> to be executed</param> /// <param name="queryableProvider">Delegate to provide <see cref="IQueryable"/> instances for given <see cref="Type"/>s</param> /// <param name="typeResolver">Optional instance of <see cref="ITypeResolver"/> to be used to translate <see cref="Aqua.TypeSystem.TypeInfo"/> into <see cref="Type"/> objects</param> /// <param name="mapper">Optional instance of <see cref="IDynamicObjectMapper"/></param> /// <param name="setTypeInformation">Function to define whether to add type information</param> /// <returns>The mapped result of the query execution</returns> public static IEnumerable <DynamicObject> ExecuteWithEntityFramework(this Expression expression, Func <Type, IQueryable> queryableProvider, ITypeResolver typeResolver = null, IDynamicObjectMapper mapper = null, Func <Type, bool> setTypeInformation = null) => new EntityFrameworkExpressionExecutor(queryableProvider, typeResolver, mapper, setTypeInformation).Execute(expression);
/// <summary> /// Creates an instance of <see cref="IQueryable" /> that utilizes the data provider specified. /// </summary> public static IQueryable CreateAsyncQueryable(this RemoteQueryableFactory factory, Type elementType, Func <Expressions.Expression, Task <IEnumerable <DynamicObject> > > dataProvider, ITypeInfoProvider typeInfoProvider = null, IDynamicObjectMapper mapper = null, Func <System.Linq.Expressions.Expression, bool> canBeEvaluatedLocally = null) { var resultMapper = new AsyncDynamicResultMapper(mapper); return(factory.CreateAsyncQueryable <IEnumerable <DynamicObject> >(elementType, dataProvider, resultMapper, typeInfoProvider, canBeEvaluatedLocally)); }
/// <summary> /// Creates an <see cref="ExpressionExecutionContext" /> for the given <see cref="Expression"/>. /// </summary> /// <param name="expression">The <see cref="Expression"/> to be executed.</param> /// <param name="dbContext">Instance of <see cref="DbContext"/> to get the <see cref="DbSet{T}"/>.</param> /// <param name="typeResolver">Optional instance of <see cref="ITypeResolver"/> to be used to translate <see cref="Aqua.TypeSystem.TypeInfo"/> into <see cref="Type"/> objects.</param> /// <param name="mapper">Optional instance of <see cref="IDynamicObjectMapper"/>.</param> /// <param name="setTypeInformation">Function to define whether to add type information.</param> /// <param name="canBeEvaluatedLocally">Function to define which expressions may be evaluated locally, and which need to be retained for execution in the database.</param> /// <returns>A new instance <see cref="ExpressionExecutionContext" />.</returns> public static ExpressionExecutionContext EntityFrameworkCoreExecutor(this Expression expression, DbContext dbContext, ITypeResolver typeResolver = null, IDynamicObjectMapper mapper = null, Func <Type, bool> setTypeInformation = null, Func <System.Linq.Expressions.Expression, bool> canBeEvaluatedLocally = null) => new ExpressionExecutionContext(new EntityFrameworkCoreExpressionExecutor(dbContext, typeResolver, mapper, setTypeInformation, canBeEvaluatedLocally), expression);