| File: System\Data\RelatedView.cs | Web Access |
| Project: src\runtime\src\libraries\System.Data.Common\src\System.Data.Common.csproj (System.Data.Common) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; using System.Diagnostics.CodeAnalysis; namespace System.Data { internal sealed class RelatedView : DataView, IFilter { private readonly DataKey? _parentKey; private readonly DataKey _childKey; private readonly DataRowView? _parentRowView; private readonly object[]? _filterValues; public RelatedView(DataColumn[] columns, object[] values) : base(columns[0].Table, false) { if (values == null) { throw ExceptionBuilder.ArgumentNull(nameof(values)); } _parentRowView = null; _parentKey = null; _childKey = new DataKey(columns, true); _filterValues = values; Debug.Assert(Table == _childKey.Table, "Key.Table Must be equal to Current Table"); base.ResetRowViewCache(); } public RelatedView(DataRowView parentRowView, DataKey parentKey, DataColumn[] childKeyColumns) : base(childKeyColumns[0].Table, false) { _filterValues = null; _parentRowView = parentRowView; _parentKey = parentKey; _childKey = new DataKey(childKeyColumns, true); Debug.Assert(Table == _childKey.Table, "Key.Table Must be equal to Current Table"); base.ResetRowViewCache(); } private object[]? GetParentValues() { if (_filterValues != null) { return _filterValues; } if (!_parentRowView!.HasRecord()) { return null; } return _parentKey!.Value.GetKeyValues(_parentRowView.GetRecord()); } public bool Invoke(DataRow row, DataRowVersion version) { object[]? parentValues = GetParentValues(); if (parentValues == null) { return false; } object[] childValues = row.GetKeyValues(_childKey, version); bool allow = childValues.AsSpan().SequenceEqual(parentValues); IFilter? baseFilter = base.GetFilter(); if (baseFilter != null) { allow &= baseFilter.Invoke(row, version); } return allow; } internal override IFilter GetFilter() => this; // move to OnModeChanged public override DataRowView AddNew() { DataRowView addNewRowView = base.AddNew(); addNewRowView.Row.SetKeyValues(_childKey, GetParentValues()!); return addNewRowView; } internal override void SetIndex(string newSort, DataViewRowState newRowStates, IFilter? newRowFilter) { SetIndex2(newSort, newRowStates, newRowFilter, false); Reset(); } public override bool Equals([NotNullWhen(true)] DataView? dv) { RelatedView? other = dv as RelatedView; if (other == null) { return false; } if (!base.Equals(dv)) { return false; } if (_filterValues != null) { return (CompareArray(_childKey.ColumnsReference, other._childKey.ColumnsReference) && CompareArray(_filterValues, other._filterValues)); } else { if (other._filterValues != null) { return false; } return (CompareArray(_childKey.ColumnsReference, other._childKey.ColumnsReference) && CompareArray(_parentKey!.Value.ColumnsReference, _parentKey.Value.ColumnsReference) && _parentRowView!.Equals(other._parentRowView)); } } private static bool CompareArray(object?[]? value1, object?[]? value2) { if (value1 == null || value2 == null) { return value1 == value2; } if (value1.Length != value2.Length) { return false; } for (int i = 0; i < value1.Length; i++) { if (value1[i] != value2[i]) return false; } return true; } } }