diff --git a/src/EntityFramework/Hierarchy/HierarchyId.cs b/src/EntityFramework/Hierarchy/HierarchyId.cs index f42b9d8fb9..16e17b4b12 100644 --- a/src/EntityFramework/Hierarchy/HierarchyId.cs +++ b/src/EntityFramework/Hierarchy/HierarchyId.cs @@ -18,7 +18,7 @@ namespace System.Data.Entity.Hierarchy public class HierarchyId : IComparable { private readonly string _hierarchyId; - private readonly int[][] _nodes; + private readonly long[][] _nodes; /// /// The Path separator character @@ -62,16 +62,16 @@ public HierarchyId(string hierarchyId) string.Format(CultureInfo.InvariantCulture, InvalidHierarchyIdExceptionMessage, hierarchyId), "hierarchyId"); } int nodesCount = nodesStr.Length - 2; - var nodes = new int[nodesCount][]; + var nodes = new long[nodesCount][]; for (int i = 0; i < nodesCount; i++) { string node = nodesStr[i + 1]; var intsStr = node.Split('.'); - var ints = new int[intsStr.Length]; + var ints = new long[intsStr.Length]; for (int j = 0; j < intsStr.Length; j++) { - int num; - if (!int.TryParse(intsStr[j], out num)) + long num; + if (!long.TryParse(intsStr[j], out num)) { throw new ArgumentException( string.Format(CultureInfo.InvariantCulture, InvalidHierarchyIdExceptionMessage, hierarchyId), "hierarchyId"); @@ -102,7 +102,7 @@ public HierarchyId GetAncestor(int n) return new HierarchyId(PathSeparator); } string hierarchyStr = PathSeparator + - string.Join(PathSeparator, _nodes.Take(GetLevel() - n).Select(IntArrayToStirng)) + string.Join(PathSeparator, _nodes.Take(GetLevel() - n).Select(LongArrayToString)) + PathSeparator; return new HierarchyId(hierarchyStr); } @@ -156,7 +156,7 @@ public HierarchyId GetDescendant(HierarchyId child1, HierarchyId child2) //decrease the last part of the last node of the 1nd child lastNode[lastNode.Length - 1]--; hierarchyStr = PathSeparator + - string.Join(PathSeparator, result._nodes.Select(IntArrayToStirng)) + string.Join(PathSeparator, result._nodes.Select(LongArrayToString)) + PathSeparator; return new HierarchyId(hierarchyStr); } @@ -167,13 +167,13 @@ public HierarchyId GetDescendant(HierarchyId child1, HierarchyId child2) //increase the last part of the last node of the 2nd child lastNode[lastNode.Length - 1]++; hierarchyStr = PathSeparator + - string.Join(PathSeparator, result._nodes.Select(IntArrayToStirng)) + string.Join(PathSeparator, result._nodes.Select(LongArrayToString)) + PathSeparator; return new HierarchyId(hierarchyStr); } var child1LastNode = child1._nodes.Last(); var child2LastNode = child2._nodes.Last(); - var cmp = CompareIntArrays(child1LastNode, child2LastNode); + var cmp = CompareLongArrays(child1LastNode, child2LastNode); if (cmp >= 0) { throw new ArgumentException( @@ -195,12 +195,12 @@ public HierarchyId GetDescendant(HierarchyId child1, HierarchyId child2) } else { - child1LastNode = child1LastNode.Concat(new[] { 1 }).ToArray(); + child1LastNode = child1LastNode.Concat(new[] { 1L }).ToArray(); } hierarchyStr = PathSeparator + - string.Join(PathSeparator, _nodes.Select(IntArrayToStirng)) + string.Join(PathSeparator, _nodes.Select(LongArrayToString)) + PathSeparator - + IntArrayToStirng(child1LastNode) + + LongArrayToString(child1LastNode) + PathSeparator; return new HierarchyId(hierarchyStr); } @@ -247,7 +247,7 @@ public bool IsDescendantOf(HierarchyId parent) } for (int i = 0; i < parent.GetLevel(); i++) { - int cmp = CompareIntArrays(_nodes[i], parent._nodes[i]); + int cmp = CompareLongArrays(_nodes[i], parent._nodes[i]); if (cmp != 0) { return false; @@ -279,12 +279,12 @@ public HierarchyId GetReparentedValue(HierarchyId oldRoot, HierarchyId newRoot) sb.Append(PathSeparator); foreach (var node in newRoot._nodes) { - sb.Append(IntArrayToStirng(node)); + sb.Append(LongArrayToString(node)); sb.Append(PathSeparator); } foreach (var node in _nodes.Skip(oldRoot.GetLevel())) { - sb.Append(IntArrayToStirng(node)); + sb.Append(LongArrayToString(node)); sb.Append(PathSeparator); } return new HierarchyId(sb.ToString()); @@ -300,18 +300,18 @@ public static HierarchyId Parse(string input) return new HierarchyId(input); } - private static string IntArrayToStirng(IEnumerable array) + private static string LongArrayToString(IEnumerable array) { return string.Join(".", array); } - private static int CompareIntArrays(int[] array1, int[] array2) + private static int CompareLongArrays(long[] array1, long[] array2) { int count = Math.Min(array1.Length, array2.Length); for (int i = 0; i < count; i++) { - int item1 = array1[i]; - int item2 = array2[i]; + long item1 = array1[i]; + long item2 = array2[i]; if (item1 < item2) { return -1; @@ -365,7 +365,7 @@ public static int Compare(HierarchyId hid1, HierarchyId hid2) { var node1 = nodes1[i]; var node2 = nodes2[i]; - int cmp = CompareIntArrays(node1, node2); + int cmp = CompareLongArrays(node1, node2); if (cmp != 0) { return cmp; diff --git a/test/UnitTests/Hierarchy/HierarchyIdUnitTests.cs b/test/UnitTests/Hierarchy/HierarchyIdUnitTests.cs index bfce17aa27..fa75a85c14 100644 --- a/test/UnitTests/Hierarchy/HierarchyIdUnitTests.cs +++ b/test/UnitTests/Hierarchy/HierarchyIdUnitTests.cs @@ -8,6 +8,26 @@ namespace System.Data.Entity.Spatial public class HierarchyIdUnitTests { + [Fact] + public void Parse_hierarchyid_with_numbers_outside_Int32_range() + { + var hid = HierarchyId.Parse("/239196746533516.54209197962074.2160059995/"); + Assert.NotNull(hid); + Assert.Equal("/239196746533516.54209197962074.2160059995/", hid.ToString()); + Assert.Equal(1, hid.GetLevel()); + } + + [Fact] + public void Compare_hierarchyids_with_large_numbers() + { + var hid1 = new HierarchyId("/239196746533516/"); + var hid2 = new HierarchyId("/239196746533517/"); + Assert.True(hid1 < hid2); + Assert.True(hid2 > hid1); + Assert.True(hid1 != hid2); + Assert.Equal(hid1, new HierarchyId("/239196746533516/")); + } + [Fact] public void Check_hierarchyid_functions() {