Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Data / System / Data / Filter / AggregateNode.cs / 1305376 / AggregateNode.cs
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// [....]
// [....]
//-----------------------------------------------------------------------------
namespace System.Data {
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.ComponentModel;
internal enum Aggregate {
None = FunctionId.none,
Sum = FunctionId.Sum,
Avg = FunctionId.Avg,
Min = FunctionId.Min,
Max = FunctionId.Max,
Count = FunctionId.Count,
StDev = FunctionId.StDev, // Statistical standard deviation
Var = FunctionId.Var, // Statistical variance
}
internal sealed class AggregateNode : ExpressionNode {
private readonly AggregateType type;
private readonly Aggregate aggregate;
private readonly bool local; // set to true if the aggregate calculated localy (for the current table)
private readonly string relationName;
private readonly string columnName;
//
private DataTable childTable;
private DataColumn column;
private DataRelation relation;
internal AggregateNode(DataTable table, FunctionId aggregateType, string columnName) :
this(table, aggregateType, columnName, true, null) {
}
internal AggregateNode(DataTable table, FunctionId aggregateType, string columnName, string relationName) :
this(table, aggregateType, columnName, false, relationName) {
}
internal AggregateNode(DataTable table, FunctionId aggregateType, string columnName, bool local, string relationName) : base(table) {
Debug.Assert(columnName != null, "Invalid parameter column name (null).");
this.aggregate = (Aggregate)(int)aggregateType;
if (aggregateType == FunctionId.Sum)
this.type = AggregateType.Sum;
else if (aggregateType == FunctionId.Avg)
this.type = AggregateType.Mean;
else if (aggregateType == FunctionId.Min)
this.type = AggregateType.Min;
else if (aggregateType == FunctionId.Max)
this.type = AggregateType.Max;
else if (aggregateType == FunctionId.Count)
this.type = AggregateType.Count;
else if (aggregateType == FunctionId.Var)
this.type = AggregateType.Var;
else if (aggregateType == FunctionId.StDev)
this.type = AggregateType.StDev;
else {
throw ExprException.UndefinedFunction(Function.FunctionName[(Int32)aggregateType]);
}
this.local = local;
this.relationName = relationName;
this.columnName = columnName;
}
internal override void Bind(DataTable table, List list) {
BindTable(table);
if (table == null)
throw ExprException.AggregateUnbound(this.ToString());
if (local) {
relation = null;
}
else {
DataRelationCollection relations;
relations = table.ChildRelations;
if (relationName == null) {
// must have one and only one relation
if (relations.Count > 1) {
throw ExprException.UnresolvedRelation(table.TableName, this.ToString());
}
if (relations.Count == 1) {
relation = relations[0];
}
else {
throw ExprException.AggregateUnbound(this.ToString());
}
}
else {
relation = relations[relationName];
}
}
childTable = (relation == null) ? table : relation.ChildTable;
this.column = childTable.Columns[columnName];
if (column == null)
throw ExprException.UnboundName(columnName);
// add column to the dependency list, do not add duplicate columns
Debug.Assert(column != null, "Failed to bind column " + columnName);
int i;
for (i = 0; i < list.Count; i++) {
// walk the list, check if the current column already on the list
DataColumn dataColumn = (DataColumn)list[i];
if (column == dataColumn) {
break;
}
}
if (i >= list.Count) {
list.Add(column);
}
// SQLBU 383715: Staleness of computed values in expression column as the relationship end columns are not being added to the dependent column list.
AggregateNode.Bind(relation, list);
}
internal static void Bind(DataRelation relation, List list)
{
if (null != relation) {
// add the ends of the relationship the expression depends on
foreach (DataColumn c in relation.ChildColumnsReference) {
if (!list.Contains(c)) {
list.Add(c);
}
}
foreach (DataColumn c in relation.ParentColumnsReference) {
if (!list.Contains(c)) {
list.Add(c);
}
}
}
}
internal override object Eval() {
return Eval(null, DataRowVersion.Default);
}
internal override object Eval(DataRow row, DataRowVersion version) {
if (childTable == null)
throw ExprException.AggregateUnbound(this.ToString());
DataRow[] rows;
if (local) {
rows = new DataRow[childTable.Rows.Count];
childTable.Rows.CopyTo(rows, 0);
}
else {
if (row == null) {
throw ExprException.EvalNoContext();
}
if (relation == null) {
throw ExprException.AggregateUnbound(this.ToString());
}
rows = row.GetChildRows(relation, version);
}
int[] records;
if (version == DataRowVersion.Proposed) {
version = DataRowVersion.Default;
}
List recordList = new List();
for (int i = 0; i < rows.Length; i++) {
if (rows[i].RowState == DataRowState.Deleted) {
if (DataRowAction.Rollback != rows[i]._action) {
continue;
}
Debug.Assert(DataRowVersion.Original == version, "wrong version");
version = DataRowVersion.Original;
}
else if ((DataRowAction.Rollback == rows[i]._action) && (rows[i].RowState == DataRowState.Added)) {
continue; // WebData 91297
}
if (version == DataRowVersion.Original && rows[i].oldRecord == -1) {
continue;
}
recordList.Add(rows[i].GetRecordFromVersion(version));
}
records = recordList.ToArray();
return column.GetAggregateValue(records, type);
}
// Helper for the DataTable.Compute method
internal override object Eval(int[] records) {
if (childTable == null)
throw ExprException.AggregateUnbound(this.ToString());
if (!local) {
throw ExprException.ComputeNotAggregate(this.ToString());
}
return column.GetAggregateValue(records, type);
}
internal override bool IsConstant() {
return false;
}
internal override bool IsTableConstant() {
return local;
}
internal override bool HasLocalAggregate() {
return local;
}
internal override bool HasRemoteAggregate() {
return !local;
}
internal override bool DependsOn(DataColumn column) {
if (this.column == column) {
return true;
}
if (this.column.Computed) {
return this.column.DataExpression.DependsOn(column);
}
return false;
}
internal override ExpressionNode Optimize() {
return this;
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- PasswordBox.cs
- UMPAttributes.cs
- WindowShowOrOpenTracker.cs
- TreeNodeCollection.cs
- CheckedPointers.cs
- HtmlTextArea.cs
- MemberHolder.cs
- TextUtf8RawTextWriter.cs
- WaitForChangedResult.cs
- PrintControllerWithStatusDialog.cs
- DesignerSerializationVisibilityAttribute.cs
- QilVisitor.cs
- EventSetter.cs
- ClientTargetCollection.cs
- BuildProvider.cs
- StatusStrip.cs
- COM2ExtendedBrowsingHandler.cs
- RegexStringValidatorAttribute.cs
- DataGridViewCheckBoxCell.cs
- GridView.cs
- ScrollChangedEventArgs.cs
- Errors.cs
- ObfuscationAttribute.cs
- BitmapEffectInputData.cs
- TileBrush.cs
- XmlSchemaGroupRef.cs
- AttachInfo.cs
- TokenBasedSet.cs
- RelatedPropertyManager.cs
- BuildResult.cs
- TypeDelegator.cs
- PermissionSetEnumerator.cs
- SessionIDManager.cs
- SpeechSynthesizer.cs
- WebBrowsableAttribute.cs
- Typography.cs
- SourceElementsCollection.cs
- ValidatorCollection.cs
- OutOfMemoryException.cs
- ListSortDescription.cs
- CaseCqlBlock.cs
- RootBuilder.cs
- ExportFileRequest.cs
- _AuthenticationState.cs
- UriParserTemplates.cs
- MediaElement.cs
- ResourceExpressionBuilder.cs
- StopStoryboard.cs
- GraphicsState.cs
- ComponentChangingEvent.cs
- CompilerGlobalScopeAttribute.cs
- TypedDataSetSchemaImporterExtensionFx35.cs
- DataRecordInternal.cs
- CheckBoxRenderer.cs
- WindowsToolbarItemAsMenuItem.cs
- PropertyItem.cs
- SafeThreadHandle.cs
- CqlParser.cs
- ProfileWorkflowElement.cs
- ToolStripComboBox.cs
- ProcessRequestArgs.cs
- GPRECT.cs
- WpfSharedXamlSchemaContext.cs
- DrawingBrush.cs
- TextTreePropertyUndoUnit.cs
- FrameworkElement.cs
- HTMLTagNameToTypeMapper.cs
- CapabilitiesAssignment.cs
- SchemaInfo.cs
- IntranetCredentialPolicy.cs
- HuffModule.cs
- DependentList.cs
- StandardBindingCollectionElement.cs
- BitmapEffectInputData.cs
- IndexingContentUnit.cs
- GraphicsContainer.cs
- SqlOuterApplyReducer.cs
- EntityContainerEmitter.cs
- KeyInfo.cs
- CommentGlyph.cs
- StylusPoint.cs
- Rfc4050KeyFormatter.cs
- EventLogPermissionAttribute.cs
- PropertyPath.cs
- CalendarButton.cs
- ManagedCodeMarkers.cs
- Membership.cs
- TabItemWrapperAutomationPeer.cs
- RectangleConverter.cs
- NumericExpr.cs
- GridViewEditEventArgs.cs
- ToolStripContentPanel.cs
- CursorConverter.cs
- FrugalMap.cs
- TickBar.cs
- Material.cs
- StackBuilderSink.cs
- WindowProviderWrapper.cs
- DecoderReplacementFallback.cs
- TypeCollectionPropertyEditor.cs