Example #1
0
        ///<summary>Creates a FilteredTable that wraps a table with the specified filter.</summary>
        public FilteredTable(ITable <TRow> table, Expression <Func <TRow, bool> > filter)
        {
            if (table == null)
            {
                throw new ArgumentNullException("table");
            }
            if (filter == null)
            {
                throw new ArgumentNullException("filter");
            }

            typedTable   = table;
            untypedTable = (Table)table;

            dependency  = DependencyParser.GetDependencyTree(table.Schema, filter);
            this.filter = filter.Compile();
            dependency.Register(untypedTable);

            writableRows = typedTable.Rows.Where(this.filter).ToList();
            Rows         = new TypedReadOnlyRowCollection <TRow>(writableRows);

            dependency.RowInvalidated += Dependency_RowInvalidated;
            //The table handlers should be added after the dependency is created.
            //This way, changes to dependent columns in our table will be handled
            //by the dependency first, and the row will be added / removed before
            //we receive ValueChanged. The one drawback is that we will then fire
            //our ValueChanged immediately after RowAdded.
            Table.RowAdded     += Table_RowAdded;
            Table.RowRemoved   += Table_RowRemoved;
            Table.ValueChanged += Table_ValueChanged;
        }
		public void ForeignKeyColumnTest() {
			Expression<Func<Row, object>> func = r =>
				r.Field<Row>("Number") != null;

			var dep = DependencyParser.GetDependencyTree(PowersSchema, func);

			Assert.IsFalse(dep.RequiresDataContext);
			var srd = (SameRowDependency)dep;

			Assert.AreEqual(0, srd.NestedDependencies.Count);
			Assert.AreEqual(1, srd.DependentColumns.Count);
			Assert.AreEqual(PowersKeyColumn, srd.DependentColumns[0]);
		}
		public void ChildRowsTest() {
			Expression<Func<Row, object>> func = r =>
				r.ChildRows("Powers");

			var dep = DependencyParser.GetDependencyTree(NumbersSchema, func);

			Assert.IsTrue(dep.RequiresDataContext);
			var ad = (AggregateDependency)dep;

			Assert.AreEqual(1, ad.Dependencies.Count);

			var prd = (ChildRowDependency)ad.Dependencies[0];
			Assert.AreEqual(0, prd.NestedDependencies.Count);
			Assert.AreEqual(0, prd.DependentColumns.Count);
			Assert.AreEqual(PowersKeyColumn.ChildRelation, prd.ChildRelation);
		}
		public void ParentRowColumnTest() {
			Expression<Func<Row, object>> func = r =>
				((Row)r["Number"])["Number"].ToString() + (r.Field<Row>("Number").Field<bool>("IsEven") ? "/" : "-");

			var dep = DependencyParser.GetDependencyTree(PowersSchema, func);

			Assert.IsTrue(dep.RequiresDataContext);
			var srd = (SameRowDependency)dep;

			Assert.AreEqual(1, srd.NestedDependencies.Count);
			Assert.AreEqual(1, srd.DependentColumns.Count);
			Assert.AreEqual(PowersKeyColumn, srd.DependentColumns[0]);

			var prd = (ParentRowDependency)srd.NestedDependencies[0];
			Assert.AreEqual(0, prd.NestedDependencies.Count);
			Assert.AreEqual(PowersKeyColumn, prd.ParentColumn);

			Assert.IsTrue(NumbersSchema.Columns.SequenceEqual(prd.DependentColumns));
		}
		public void ChildRowsColumnTest() {
			Expression<Func<Row, object>> func = r =>
			-(int)r["Number"] + r.ChildRows("Powers").Last().Field<int>("Exponent") * r.ChildRows("Powers").Sum(p => (int)p["Value"] / p.Field<long>("Number"));

			var dep = DependencyParser.GetDependencyTree(NumbersSchema, func);

			Assert.IsTrue(dep.RequiresDataContext);
			var srd = (SameRowDependency)dep;

			Assert.AreEqual(1, srd.NestedDependencies.Count);
			Assert.AreEqual(1, srd.DependentColumns.Count);
			Assert.AreEqual(NumbersSchema.Columns[0], srd.DependentColumns[0]);

			var crd = (ChildRowDependency)srd.NestedDependencies[0];
			Assert.AreEqual(0, crd.NestedDependencies.Count);
			Assert.AreEqual(PowersKeyColumn.ChildRelation, crd.ChildRelation);

			Assert.IsTrue(PowersSchema.Columns.OrderBy(c => c.Name).SequenceEqual(crd.DependentColumns.OrderBy(c => c.Name)));
		}
		public void NestedRelationTest() {
			Expression<Func<Row, object>> func = r =>
				from power in ((Row)r["Number"]).ChildRows("Powers")
				where (int)power["Exponent"] % 2 == 0
				select power.Field<int>("Value")
					 / power.Field<Row>("Number").ChildRows("Powers").Sum(p => p.Field<int>("Value"));

			var dep = DependencyParser.GetDependencyTree(PowersSchema, func);

			Assert.IsTrue(dep.RequiresDataContext);

			var srd = (SameRowDependency)dep;
			Assert.AreEqual(1, srd.NestedDependencies.Count);
			Assert.AreEqual(1, srd.DependentColumns.Count);
			Assert.AreEqual(PowersKeyColumn, srd.DependentColumns[0]);

			var prd = (ParentRowDependency)srd.NestedDependencies[0];	// ((Row)r["Number"]).
			Assert.AreEqual(0, prd.DependentColumns.Count);
			Assert.AreEqual(1, prd.NestedDependencies.Count);
			Assert.AreEqual(PowersKeyColumn, prd.ParentColumn);

			var crd = (ChildRowDependency)prd.NestedDependencies[0];	// ((Row)r["Number"]).ChildRows("Powers") (In from clause)
			Assert.AreEqual(1, crd.NestedDependencies.Count);
			Assert.AreEqual(PowersKeyColumn.ChildRelation, crd.ChildRelation);

			Assert.IsTrue(PowersSchema.Columns.OrderBy(c => c.Name).SequenceEqual(crd.DependentColumns.OrderBy(c => c.Name)));

			prd = (ParentRowDependency)crd.NestedDependencies[0];	// / power.Field<Row>("Number").
			Assert.AreEqual(0, prd.DependentColumns.Count);
			Assert.AreEqual(1, prd.NestedDependencies.Count);
			Assert.AreEqual(PowersKeyColumn, prd.ParentColumn);


			crd = (ChildRowDependency)prd.NestedDependencies[0];	// Field<Row>("Number").ChildRows("Powers") (in select clause)
			Assert.AreEqual(0, crd.NestedDependencies.Count);
			Assert.AreEqual(1, crd.DependentColumns.Count);
			Assert.AreEqual(PowersKeyColumn.ChildRelation, crd.ChildRelation);

			Assert.AreEqual(PowersSchema.Columns["Value"], crd.DependentColumns[0]);
		}
Example #7
0
        ///<summary>Adds a calculated column to the schema.</summary>
        ///<typeparam name="TValue">The type of the column's value.</typeparam>
        ///<typeparam name="TRow">The strongly-typed row used to calculate the column's value.</typeparam>
        ///<param name="name">The name of the column.</param>
        ///<param name="expression">An expression used to calculate the column's value.</param>
        public CalculatedColumn AddCalculatedColumn <TRow, TValue>(string name, Expression <Func <TRow, TValue> > expression) where TRow : Row
        {
            if (expression == null)
            {
                throw new ArgumentNullException("expression");
            }
            var compiled = expression.Compile();

            return(AddColumn(new CalculatedColumn(Schema, name, typeof(TValue), row => compiled((TRow)row), () => DependencyParser.GetDependencyTree(Schema, expression))));
        }