private Expression ExecuteProjection(ProjectionExpression projection, bool okayToDefer, QueryCommand command, Expression[] values) { okayToDefer &= (receivingMember != null && policy.IsDeferLoaded(receivingMember)); Scope saveScope = scope; ParameterExpression reader = Expression.Parameter(typeof(FieldReader), "r" + nReaders++); scope = new Scope(scope, reader, projection.Select.Alias, projection.Select.Columns); LambdaExpression projector = Expression.Lambda(Visit(projection.Projector), reader); scope = saveScope; EntryMapping entity = EntityFinder.Find(projection.Projector); string methExecute = okayToDefer ? "ExecuteDeferred" : "Execute"; // call low-level execute directly on supplied DbQueryProvider Expression result = Expression.Call(executor, methExecute, new[] { projector.Body.Type }, Expression.Constant(command), projector, Expression.Constant(entity, typeof(EntryMapping)), Expression.NewArrayInit(typeof(object), values)); if (projection.Aggregator != null) { // apply aggregator result = DbExpressionReplacer.Replace(projection.Aggregator.Body, projection.Aggregator.Parameters[0], result); } return(result); }
protected override Expression VisitEntity(EntryExpression entity) { if (this.entity == null) { this.entity = entity.Entry; } return(entity); }
/// <summary> /// Determines if a relationship property refers to a single entity (as opposed to a collection.) /// </summary> /// <param name="member"> </param> /// <returns> </returns> public virtual bool IsSingletonRelationship(EntryMapping entry, MemberInfo member) { if (!IsRelationship(entry, member)) { return(false); } Type ieType = TypeHelper.FindIEnumerable(TypeHelper.GetMemberType(member)); return(ieType == null); }
protected ISessionTable GetTable(EntryMapping entity) { ISessionTable table; if (!tables.TryGetValue(entity, out table)) { table = CreateTable(entity); tables.Add(entity, table); } return(table); }
protected virtual Expression BuildExecuteBatch(BatchExpression batch) { // parameterize query Expression operation = Parameterize(batch.Operation.Body); string commandText = linguist.Format(operation); ReadOnlyCollection <NamedValueExpression> namedValues = NamedValueGatherer.Gather(operation); var command = new QueryCommand(commandText, namedValues.Select(v => new QueryParameter(v.Name, v.Type, v.QueryType))); Expression[] values = namedValues.Select(v => Expression.Convert(Visit(v.Value), typeof(object))).ToArray(); Expression paramSets = Expression.Call(typeof(Enumerable), "Select", new[] { batch.Operation.Parameters[1].Type, typeof(object[]) }, batch.Input, Expression.Lambda(Expression.NewArrayInit(typeof(object), values), new[] { batch.Operation.Parameters[1] })); Expression plan = null; ProjectionExpression projection = ProjectionFinder.FindProjection(operation); if (projection != null) { Scope saveScope = scope; ParameterExpression reader = Expression.Parameter(typeof(FieldReader), "r" + nReaders++); scope = new Scope(scope, reader, projection.Select.Alias, projection.Select.Columns); LambdaExpression projector = Expression.Lambda(Visit(projection.Projector), reader); scope = saveScope; EntryMapping entity = EntityFinder.Find(projection.Projector); command = new QueryCommand(command.CommandText, command.Parameters); plan = Expression.Call(executor, "ExecuteBatch", new[] { projector.Body.Type }, Expression.Constant(command), paramSets, projector, Expression.Constant(entity, typeof(EntryMapping)), batch.BatchSize, batch.Stream); } else { plan = Expression.Call(executor, "ExecuteBatch", null, Expression.Constant(command), paramSets, batch.BatchSize, batch.Stream); } return(plan); }
/// <summary> /// Get a query expression that selects all entities from a table /// </summary> /// <param name="rowType"> </param> /// <returns> </returns> public abstract ProjectionExpression GetQueryExpression(EntryMapping entity);
protected virtual ISessionTable CreateTable(EntryMapping entry) { return((ISessionTable)Activator.CreateInstance(typeof(TrackedTable <>).MakeGenericType(entry.Type), new object[] { this, entry })); }
/// <summary> /// Determines if a property is mapped as a relationship /// </summary> /// <param name="entity"> </param> /// <param name="member"> </param> /// <returns> </returns> public abstract bool IsRelationship(EntryMapping entity, MemberInfo member);
public abstract bool IsPrimaryKey(EntryMapping entity, MemberInfo member);
public EntryInfo(object instance, EntryMapping mapping) { this.instance = instance; this.mapping = mapping; }
/// <summary> /// Get an expression that represents the insert-or-update operation for the specified instance. /// </summary> /// <param name="entity"> </param> /// <param name="instance"> </param> /// <param name="updateCheck"> </param> /// <param name="resultSelector"> </param> /// <returns> </returns> public abstract Expression GetInsertOrUpdateExpression(EntryMapping entity, Expression instance, LambdaExpression updateCheck, LambdaExpression resultSelector);
/// <summary> /// Get an expression that represents the insert operation for the specified instance. /// </summary> /// <param name="entity"> </param> /// <param name="instance"> The instance to insert. </param> /// <param name="selector"> A lambda expression that computes a return value from the operation. </param> /// <returns> </returns> public abstract Expression GetInsertExpression(EntryMapping entity, Expression instance, LambdaExpression selector);
public TrackedTable(EntrySession session, EntryMapping entity) : base(session, entity) { tracked = new Dictionary <T, TrackedItem>(); identityCache = new Dictionary <object, T>(); }
public SessionTable(EntrySession session, EntryMapping entity) : base(session.sessionProvider, typeof(ISessionTable <T>)) { this.session = session; this.entity = entity; underlyingTable = this.session.Provider.GetEntry <T>(); }
private Func <FieldReader, T> Wrap <T>(Func <FieldReader, T> fnProjector, EntryMapping entity) { Func <FieldReader, T> fnWrapped = (fr) => (T)session.OnEntityMaterialized(entity, fnProjector(fr)); return(fnWrapped); }
public override IEnumerable <T> ExecuteDeferred <T>(QueryCommand query, Func <FieldReader, T> fnProjector, EntryMapping entity, object[] paramValues) { return(executor.ExecuteDeferred(query, Wrap(fnProjector, entity), entity, paramValues)); }
public override IEnumerable <T> ExecuteBatch <T>(QueryCommand query, IEnumerable <object[]> paramSets, Func <FieldReader, T> fnProjector, EntryMapping entity, int batchSize, bool stream) { return(executor.ExecuteBatch(query, paramSets, Wrap(fnProjector, entity), entity, batchSize, stream)); }
/// <summary> /// Gets an expression that constructs an entity instance relative to a root. The root is most often a TableExpression, but may be any other experssion such as a ConstantExpression. /// </summary> /// <param name="root"> </param> /// <param name="entity"> </param> /// <returns> </returns> public abstract EntryExpression GetEntityExpression(Expression root, EntryMapping entity);
/// <summary> /// Get an expression for a mapped property relative to a root expression. The root is either a TableExpression or an expression defining an entity instance. /// </summary> /// <param name="root"> </param> /// <param name="entity"> </param> /// <param name="member"> </param> /// <returns> </returns> public abstract Expression GetMemberExpression(Expression root, EntryMapping entity, MemberInfo member);
private object OnEntityMaterialized(EntryMapping entity, object instance) { var table = (IEntitySessionTable)GetTable(entity); return(table.OnEntityMaterialized(instance)); }
/// <summary> /// Get an expression that represents the update operation for the specified instance. /// </summary> /// <param name="entity"> </param> /// <param name="instance"> </param> /// <param name="updateCheck"> </param> /// <param name="selector"> </param> /// <param name="else"> </param> /// <returns> </returns> public abstract Expression GetUpdateExpression(EntryMapping entity, Expression instance, Expression updateCheck, LambdaExpression selector, Expression @else);
public abstract object GetPrimaryKey(EntryMapping entity, object instance);
/// <summary> /// Get an expression that represents the delete operation for the specified instance. /// </summary> /// <param name="entity"> </param> /// <param name="instance"> </param> /// <param name="deleteCheck"> </param> /// <returns> </returns> public abstract Expression GetDeleteExpression(EntryMapping entity, Expression instance, LambdaExpression deleteCheck);
public abstract Expression GetPrimaryKeyQuery(EntryMapping entity, Expression source, Expression[] keys);
public abstract IEnumerable <MemberInfo> GetMappedMembers(EntryMapping entity);
public abstract IEnumerable <EntryInfo> GetDependingEntities(EntryMapping entity, object instance);
public virtual IEnumerable <MemberInfo> GetPrimaryKeyMembers(EntryMapping entry) { return(entry.Members.Where(m => m.Identifier).Select(m => m.MemberInfo)); }
public abstract bool IsModified(EntryMapping entity, object instance, object original);
public abstract object CloneEntity(EntryMapping entity, object instance);
public TableExpression(TableAlias alias, EntryMapping entry, string name) : base(DbExpressionType.Table, typeof(void), alias) { this.entry = entry; this.name = name; }