1 //---------------------------------------------------------------------
2 // <copyright file="SpanIndex.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
7 // @backupowner Microsoft
8 //---------------------------------------------------------------------
11 using System
.Collections
.Generic
;
12 using System
.Diagnostics
;
13 using System
.Data
.Common
;
14 using System
.Data
.Common
.Utils
;
15 using System
.Data
.Metadata
.Edm
;
16 using System
.Data
.Common
.CommandTrees
;
18 namespace System
.Data
.Objects
.Internal
21 /// An index containing information about how the query was spanned
22 /// This helps to determine how to materialize the query result
24 internal sealed class SpanIndex
29 /// Helper class to compare two RowTypes using EdmEquals instead of reference equality.
31 sealed private class RowTypeEqualityComparer
: IEqualityComparer
<RowType
>
33 private RowTypeEqualityComparer() { }
34 internal static readonly RowTypeEqualityComparer Instance
= new RowTypeEqualityComparer();
36 #region IEqualityComparer<RowType> Members
38 public bool Equals(RowType x
, RowType y
)
40 if (x
== null || y
== null)
45 return x
.EdmEquals(y
);
48 public int GetHashCode(RowType obj
)
50 return obj
.Identity
.GetHashCode();
57 // When a query is spanned, the result is always a RowType
58 // The _spanMap index maps RowTypes that are a span result to a map between
59 // column ordinal and end member metadata of the type that is spanned
60 private Dictionary
<RowType
, Dictionary
<int, AssociationEndMember
>> _spanMap
;
62 // A map from a spanned RowType (or parent RowType) to the original TypeUsage prior
63 // to the query being rewritten
64 private Dictionary
<RowType
, TypeUsage
> _rowMap
;
70 internal void AddSpannedRowType(RowType spannedRowType
, TypeUsage originalRowType
)
72 Debug
.Assert(spannedRowType
!= null, "Spanned RowType cannot be null");
73 Debug
.Assert(originalRowType
!= null, "Original RowType cannot be null");
74 Debug
.Assert(originalRowType
.EdmType
.BuiltInTypeKind
== BuiltInTypeKind
.RowType
, "Original RowType must be a RowType");
78 _rowMap
= new Dictionary
<RowType
, TypeUsage
>(RowTypeEqualityComparer
.Instance
);
81 _rowMap
[spannedRowType
] = originalRowType
;
84 internal TypeUsage
GetSpannedRowType(RowType spannedRowType
)
87 if (_rowMap
!= null && _rowMap
.TryGetValue(spannedRowType
, out retType
))
94 internal bool HasSpanMap(RowType spanRowType
)
96 Debug
.Assert(spanRowType
!= null, "Span RowType cannot be null");
102 return _spanMap
.ContainsKey(spanRowType
);
105 internal void AddSpanMap(RowType rowType
, Dictionary
<int, AssociationEndMember
> columnMap
)
107 Debug
.Assert(rowType
!= null, "Span row type cannot be null");
108 Debug
.Assert(columnMap
!= null, "Span column map cannot be null");
110 if (null == _spanMap
)
112 _spanMap
= new Dictionary
<RowType
, Dictionary
<int, AssociationEndMember
>>(RowTypeEqualityComparer
.Instance
);
115 _spanMap
[rowType
] = columnMap
;
118 internal Dictionary
<int, AssociationEndMember
> GetSpanMap(RowType rowType
)
120 Dictionary
<int, AssociationEndMember
> retMap
= null;
121 if (_spanMap
!= null && _spanMap
.TryGetValue(rowType
, out retMap
))