internal void EvaluateDependentExpressions(List<DataColumn> columns, DataRow row, DataRowVersion version, List<DataRow> cachedRows)
{
if (columns == null)
{
return;
}
//Expression evaluation is done first over same table expressions.
int count = columns.Count;
for (int i = 0; i < count; i++)
{
if (columns[i].Table == this)
{
// if this column is in my table
DataColumn dc = columns[i];
if (dc.DataExpression != null && dc.DataExpression.HasLocalAggregate())
{
// if column expression references a local Table aggregate we need to recalc it for the each row in the local table
DataRowVersion expressionVersion = (version == DataRowVersion.Proposed) ? DataRowVersion.Default : version;
bool isConst = dc.DataExpression.IsTableAggregate(); //is expression constant for entire table?
object newValue = null;
if (isConst)
{
//if new value, just compute once
newValue = dc.DataExpression.Evaluate(row, expressionVersion);
}
for (int j = 0; j < Rows.Count; j++)
{
//evaluate for all rows in the table
DataRow dr = Rows[j];
if (dr.RowState == DataRowState.Deleted)
{
continue;
}
else if (expressionVersion == DataRowVersion.Original && (dr._oldRecord == -1 || dr._oldRecord == dr._newRecord))
{
continue;
}
if (!isConst)
{
newValue = dc.DataExpression.Evaluate(dr, expressionVersion);
}
SilentlySetValue(dr, dc, expressionVersion, newValue);
}
}
else
{
if (row.RowState == DataRowState.Deleted)
{
continue;
}
else if (version == DataRowVersion.Original && (row._oldRecord == -1 || row._oldRecord == row._newRecord))
{
continue;
}
SilentlySetValue(row, dc, version, dc.DataExpression == null ? dc.DefaultValue : dc.DataExpression.Evaluate(row, version));
}
}
}
// now do expression evaluation for expression columns other tables.
count = columns.Count;
for (int i = 0; i < count; i++)
{
DataColumn dc = columns[i];
// if this column is NOT in my table or it is in the table and is not a local aggregate (self refs)
if (dc.Table != this || (dc.DataExpression != null && !dc.DataExpression.HasLocalAggregate()))
{
DataRowVersion foreignVer = (version == DataRowVersion.Proposed) ? DataRowVersion.Default : version;
// first - evaluate expressions for cachedRows (deletes & updates)
if (cachedRows != null)
{
foreach (DataRow cachedRow in cachedRows)
{
if (cachedRow.Table != dc.Table)
{
continue;
}
// don't update original version if child row doesn't have an oldRecord.
if (foreignVer == DataRowVersion.Original && cachedRow._newRecord == cachedRow._oldRecord)
{
continue;
}
if (cachedRow != null && ((cachedRow.RowState != DataRowState.Deleted) && (version != DataRowVersion.Original || cachedRow._oldRecord != -1)))
{
// if deleted GetRecordFromVersion will throw
object newValue = dc.DataExpression.Evaluate(cachedRow, foreignVer);
SilentlySetValue(cachedRow, dc, foreignVer, newValue);
}
}
}
// next check parent relations
for (int j = 0; j < ParentRelations.Count; j++)
{
DataRelation relation = ParentRelations[j];
if (relation.ParentTable != dc.Table)
{
continue;
}
foreach (DataRow parentRow in row.GetParentRows(relation, version))
{
if (cachedRows != null && cachedRows.Contains(parentRow))
{
continue;
}
// don't update original version if child row doesn't have an oldRecord.
if (foreignVer == DataRowVersion.Original && parentRow._newRecord == parentRow._oldRecord)
{
continue;
}
if (parentRow != null && ((parentRow.RowState != DataRowState.Deleted) && (version != DataRowVersion.Original || parentRow._oldRecord != -1)))
{
// if deleted GetRecordFromVersion will throw
object newValue = dc.DataExpression.Evaluate(parentRow, foreignVer);
SilentlySetValue(parentRow, dc, foreignVer, newValue);
}
}
}
// next check child relations
for (int j = 0; j < ChildRelations.Count; j++)
{
DataRelation relation = ChildRelations[j];
if (relation.ChildTable != dc.Table)
{
continue;
}
foreach (DataRow childRow in row.GetChildRows(relation, version))
{
// don't update original version if child row doesn't have an oldRecord.
if (cachedRows != null && cachedRows.Contains(childRow))
{
continue;
}
if (foreignVer == DataRowVersion.Original && childRow._newRecord == childRow._oldRecord)
{
continue;
}
if (childRow != null && ((childRow.RowState != DataRowState.Deleted) && (version != DataRowVersion.Original || childRow._oldRecord != -1)))
{
// if deleted GetRecordFromVersion will throw
object newValue = dc.DataExpression.Evaluate(childRow, foreignVer);
SilentlySetValue(childRow, dc, foreignVer, newValue);
}
}
}
}
}
}
}