protected override Expression VisitMember(MemberExpression node) { // ---------------------------------------------------- // original: // dbParam.DatabaseTable // ---------------------------------------------------- // transformed: // executionContextParam.Database.Tables.FindTable<T> // ---------------------------------------------------- if (typeof(IDatabase).IsAssignableFrom(node.Member.DeclaringType) && node.Expression is ParameterExpression) { Type entityType = DatabaseReflectionHelper.GetTableEntityType(node.Type); // Check if ITable<> if (entityType != null) { Expression database = Expression.Property( this.context.Parameter, DatabaseMembers.ExecutionContext_Database); Expression tables = Expression.Property( database, DatabaseMembers.Database_Tables); return(Expression.Call(DatabaseMembers.TableCollectionExtensions_FindTable.MakeGenericMethod(entityType), tables)); } } return(base.VisitMember(node)); }
private static object CreateAndInsertEntity(ITable table, IList <MemberBinding> memberBindings, Transaction transaction) { object newEntity = Effort.Shared.Internal.CreateEntityHelper.Create(table, memberBindings); DatabaseReflectionHelper.InsertEntity(table, newEntity, transaction); return(newEntity); }
public int ExecuteNonQuery(ActionContext context) { ITable table = null; Expression expr = DbCommandActionHelper.GetEnumeratorExpression(this.commandTree.Predicate, this.commandTree, context.DbContainer, out table); IQueryable entitiesToDelete = DatabaseReflectionHelper.CreateTableQuery(expr, context.DbContainer.Internal); return(DatabaseReflectionHelper.DeleteEntities(entitiesToDelete, context.Transaction)); }
public int ExecuteNonQuery(ActionContext context) { ITable table = null; Expression expr = DbCommandActionHelper.GetEnumeratorExpression(this.commandTree.Predicate, this.commandTree, context.DbContainer, out table); IQueryable entitiesToUpdate = DatabaseReflectionHelper.CreateTableQuery(expr, context.DbContainer.Internal); Type type = TypeHelper.GetElementType(table.GetType()); // Collect the SetClause DbExpressions into a dictionary IDictionary <string, DbExpression> setClauses = DbCommandActionHelper.GetSetClauseExpressions(this.commandTree.SetClauses); // Collection for collection member bindings IList <MemberBinding> memberBindings = new List <MemberBinding>(); TransformVisitor transform = new TransformVisitor(context.DbContainer.TypeConverter); // Setup context for the predicate ParameterExpression param = Expression.Parameter(type, "context"); using (transform.CreateVariable(param, this.commandTree.Target.VariableName)) { // Initialize member bindings foreach (PropertyInfo property in type.GetProperties()) { Expression setter = null; // Check if member has set clause if (setClauses.ContainsKey(property.Name)) { setter = transform.Visit(setClauses[property.Name]); } // If setter was found, insert it if (setter != null) { // Type correction setter = ExpressionHelper.CorrectType(setter, property.PropertyType); memberBindings.Add(Expression.Bind(property, setter)); } } } Expression updater = Expression.Lambda( Expression.MemberInit(Expression.New(type), memberBindings), param); return(DatabaseReflectionHelper.UpdateEntities(entitiesToUpdate, updater, context.Transaction).Count()); }
public DbDataReader ExecuteDataReader(ActionContext context) { TransformVisitor visitor = new TransformVisitor(context.DbContainer.TypeConverter); visitor.TableProvider = context.DbContainer; // Transform command tree Expression queryExpression = visitor.Visit(this.commandTree.Query); LambdaExpression query = Expression.Lambda(queryExpression, Expression.Parameter(typeof(IDatabase))); // Create a stored procedure from the expression ISharedStoredProcedure procedure = DatabaseReflectionHelper.CreateSharedStoredProcedure(query); // Format the parameter values IDictionary <string, object> parameters = DbCommandActionHelper.FormatParameters( context.Parameters, procedure.Parameters, context.DbContainer.TypeConverter); IEnumerable result = null; if (context.Transaction != null) { result = procedure.Execute( context.DbContainer.Internal, parameters, context.Transaction); } else { result = procedure.Execute( context.DbContainer.Internal, parameters); } List <FieldDescription> fields = GetReturningFields(this.commandTree); return(new EffortDataReader( result, -1, fields.ToArray(), context.DbContainer)); }
private static object CreateAndInsertEntity(ITable table, IList <MemberBinding> memberBindings, Transaction transaction) { LambdaExpression expression = Expression.Lambda( Expression.MemberInit( Expression.New(table.EntityType), memberBindings)); Delegate factory = expression.Compile(); object newEntity = factory.DynamicInvoke(); DatabaseReflectionHelper.InsertEntity(table, newEntity, transaction); return(newEntity); }
protected override Expression VisitMember(MemberExpression node) { Type type = ReflectionHelper.GetMemberType(node.Member); if (typeof(ITable).IsAssignableFrom(type)) { Type entityType = DatabaseReflectionHelper.GetTableEntityType(node.Type); // Check if ITable<> if (entityType != null) { this.entityTypes.Add(entityType); } } return(base.VisitMember(node)); }
protected override Expression VisitMethodCall(MethodCallExpression node) { // ---------------------------------------------------- // original: // executionContext.Database.Tables.FindTable<> OR // dbConst.Tables.FindTable<> OR // const.db.Tables.FindTable<> // ---------------------------------------------------- // transformed: // tableConstant // ---------------------------------------------------- if (!node.Method.IsGenericMethod || node.Method.GetGenericMethodDefinition() != DatabaseMembers.TableCollectionExtensions_FindTable) { return(base.VisitMethodCall(node)); } Type entityType = DatabaseReflectionHelper.GetTableEntityType(node.Type); if (entityType == null) { // TODO: This should not happen, log this return(base.VisitMethodCall(node)); } MemberExpression tablesProp = node.Arguments[0] as MemberExpression; if (tablesProp == null || tablesProp.Member != DatabaseMembers.Database_Tables) { return(base.VisitMethodCall(node)); } IDatabase database = this.FindDatabase(tablesProp.Expression); if (database == null) { // TODO: This should not happen, log this return(base.VisitMethodCall(node)); } ITable table = database.Tables.FindTable(entityType); return(Expression.Constant(table)); }
protected override Expression VisitConstant(ConstantExpression node) { //// ---------------------------------------------- //// original: //// DatabaseTable //// ---------------------------------------------- //// transformed: //// DatabaseTable.SelectAll<> //// ---------------------------------------------- Type entityType = DatabaseReflectionHelper.GetTableEntityType(node.Type); if (entityType != null) { return(CreateSelectTableExpression(node, entityType)); } return(base.VisitConstant(node)); }
protected override Expression VisitMethodCall(MethodCallExpression node) { //// ---------------------------------------------- //// original: //// dbParam.FindTable<> //// ---------------------------------------------- //// transformed: //// dbParam.FindTable<>.SelectAll<> //// ---------------------------------------------- Type entityType = DatabaseReflectionHelper.GetTableEntityType(node.Type); if (entityType != null && node.Method.IsGenericMethod && node.Method.GetGenericMethodDefinition() == DatabaseMembers.TableCollectionExtensions_FindTable) { return(CreateSelectTableExpression(node, entityType)); } return(base.VisitMethodCall(node)); }
public void Initialize(DbSchema schema) { // TODO: locking Stopwatch fullTime = Stopwatch.StartNew(); Stopwatch partialTime = Stopwatch.StartNew(); this.Logger.Write("Database creation started..."); this.EnsureInitializedDatabase(); // Temporary dictionary Dictionary <string, ITable> tables = new Dictionary <string, ITable>(); this.Logger.Write("Creating tables..."); partialTime.Restart(); foreach (DbTableInfo tableInfo in schema.Tables) { ITable table = DatabaseReflectionHelper.CreateTable( this.Internal, tableInfo.EntityType, (IKeyInfo)tableInfo.PrimaryKeyInfo, tableInfo.IdentityField, tableInfo.ConstraintFactories); tables.Add(tableInfo.TableName, table); } this.Logger.Write( "Tables created in {0:0.0} ms", partialTime.Elapsed.TotalMilliseconds); this.Logger.Write("Adding initial data..."); partialTime.Restart(); // Add initial data to the tables using (ITableDataLoaderFactory loaderFactory = this.CreateDataLoaderFactory()) { foreach (DbTableInfo tableInfo in schema.Tables) { // Get the table reference from the temporary dictionary ITable table = tables[tableInfo.TableName]; // Return initial entity data and materialize them IEnumerable <object> data = ObjectLoader.Load(loaderFactory, tableInfo); DatabaseReflectionHelper.InitializeTableData(table, data); } } this.Logger.Write( "Initial data added in {0:0.0} ms", partialTime.Elapsed.TotalMilliseconds); this.Logger.Write("Building additional indexes..."); partialTime.Restart(); foreach (DbTableInfo tableInfo in schema.Tables) { ITable table = tables[tableInfo.TableName]; foreach (IKeyInfo key in tableInfo.UniqueKeys) { DatabaseReflectionHelper.CreateIndex(table, key, true); } foreach (IKeyInfo key in tableInfo.ForeignKeys) { DatabaseReflectionHelper.CreateIndex(table, key, false); } } this.Logger.Write( "Additional indexes built in {0:0.0} ms", partialTime.Elapsed.TotalMilliseconds); this.Logger.Write("Creating and verifying associations..."); partialTime.Restart(); foreach (DbRelationInfo relation in schema.Relations) { DatabaseReflectionHelper.CreateAssociation(this.Internal, relation); } this.Logger.Write( "Associations created and verfied in {0:0.0} ms", partialTime.Elapsed.TotalMilliseconds); this.Logger.Write( "Database creation finished in {0:0.0} ms", fullTime.Elapsed.TotalMilliseconds); }
public DbDataReader ExecuteDataReader(ActionContext context) { FieldDescription[] returningFields = DbCommandActionHelper.GetReturningFields(this.commandTree.Returning); IList <IDictionary <string, object> > returningEntities = new List <IDictionary <string, object> >(); ITable table = null; Expression expr = DbCommandActionHelper.GetEnumeratorExpression(this.commandTree.Predicate, this.commandTree, context.DbContainer, out table); IQueryable entitiesToUpdate = DatabaseReflectionHelper.CreateTableQuery(expr, context.DbContainer.Internal); Type type = TypeHelper.GetElementType(table.GetType()); // Collect the SetClause DbExpressions into a dictionary IDictionary <string, DbExpression> setClauses = DbCommandActionHelper.GetSetClauseExpressions(this.commandTree.SetClauses); // Collection for collection member bindings IList <MemberBinding> memberBindings = new List <MemberBinding>(); TransformVisitor transform = new TransformVisitor(context.DbContainer); // Setup context for the predicate ParameterExpression param = Expression.Parameter(type, "context"); using (transform.CreateVariable(param, this.commandTree.Target.VariableName)) { // Initialize member bindings foreach (PropertyInfo property in type.GetProperties()) { Expression setter = null; // Check if member has set clause if (setClauses.ContainsKey(property.Name)) { setter = transform.Visit(setClauses[property.Name]); } // If setter was found, insert it if (setter != null) { // Type correction setter = ExpressionHelper.CorrectType(setter, property.PropertyType); memberBindings.Add(Expression.Bind(property, setter)); } } } Expression updater = Expression.Lambda( Expression.MemberInit(Expression.New(type), memberBindings), param); IEnumerable <object> updatedEntities = DatabaseReflectionHelper.UpdateEntities(entitiesToUpdate, updater, context.Transaction); int affectedRecords = 0; foreach (object entity in updatedEntities) { affectedRecords++; Dictionary <string, object> returningEntity = DbCommandActionHelper.CreateReturningEntity(context, returningFields, entity); returningEntities.Add(returningEntity); } return(new EffortDataReader( returningEntities, affectedRecords, returningFields, context.DbContainer)); }