///<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]); }
///<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)))); }