-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
Showing
41 changed files
with
2,838 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 16 additions & 0 deletions
16
src/EFCore.SqlServer.Abstractions/EFCore.SqlServer.Abstractions.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>netstandard2.0</TargetFramework> | ||
<AssemblyName>EntityFrameworkCore.SqlServer.HierarchyId.Abstractions</AssemblyName> | ||
<RootNamespace>Microsoft.EntityFrameworkCore</RootNamespace> | ||
<Description>Common abstractions for using hierarchyid with EF Core</Description> | ||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> | ||
<GenerateDocumentationFile>true</GenerateDocumentationFile> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="dotMorten.Microsoft.SqlServer.Types" Version="1.5.0" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,217 @@ | ||
using System; | ||
using System.IO; | ||
using Microsoft.SqlServer.Types; | ||
|
||
namespace Microsoft.EntityFrameworkCore | ||
{ | ||
/// <summary> | ||
/// Represents a position in a hierarchical structure, specifying depth and breadth. | ||
/// </summary> | ||
public class HierarchyId : IComparable | ||
{ | ||
private SqlHierarchyId _value; | ||
|
||
private HierarchyId(SqlHierarchyId value) | ||
{ | ||
if (value.IsNull) | ||
throw new ArgumentNullException(nameof(value)); | ||
|
||
_value = value; | ||
} | ||
|
||
/// <summary> | ||
/// Gets the root node of the hierarchy. | ||
/// </summary> | ||
/// <returns>The root node of the hierarchy.</returns> | ||
public static HierarchyId GetRoot() | ||
=> new HierarchyId(SqlHierarchyId.GetRoot()); | ||
|
||
/// <summary> | ||
/// Converts the canonical string representation of a node to a <see cref="HierarchyId"/> value. | ||
/// </summary> | ||
/// <param name="input">The string representation of a node.</param> | ||
/// <returns>A <see cref="HierarchyId"/> value.</returns> | ||
public static HierarchyId Parse(string input) | ||
=> Wrap(SqlHierarchyId.Parse(input)); | ||
|
||
/// <summary> | ||
/// Reads a <see cref="HierarchyId"/> value from the specified reader. | ||
/// </summary> | ||
/// <param name="reader">The reader.</param> | ||
/// <returns>A <see cref="HierarchyId"/> value.</returns> | ||
public static HierarchyId Read(BinaryReader reader) | ||
{ | ||
var hid = new SqlHierarchyId(); | ||
hid.Read(reader); | ||
return Wrap(hid); | ||
} | ||
|
||
/// <summary> | ||
/// Writes this <see cref="HierarchyId"/> value to the specified writer. | ||
/// </summary> | ||
/// <param name="writer">The writer.</param> | ||
public void Write(BinaryWriter writer) | ||
{ | ||
_value.Write(writer); | ||
} | ||
|
||
/// <inheritdoc/> | ||
public int CompareTo(object obj) | ||
=> _value.CompareTo( | ||
obj is HierarchyId other | ||
? other._value | ||
: obj); | ||
|
||
/// <inheritdoc/> | ||
public override bool Equals(object obj) | ||
=> _value.Equals( | ||
obj is HierarchyId other | ||
? other._value | ||
: obj); | ||
|
||
/// <summary> | ||
/// Gets the node <paramref name="n"/> levels up the hierarchical tree. | ||
/// </summary> | ||
/// <param name="n">The number of levels to ascend in the hierarchy.</param> | ||
/// <returns>A <see cref="HierarchyId"/> value representing the <paramref name="n"/>th ancestor of this node or null if <paramref name="n"/> is greater than <see cref="GetLevel"/>.</returns> | ||
/// <exception cref="ArgumentOutOfRangeException"><paramref name="n"/> is negative.</exception> | ||
public HierarchyId GetAncestor(int n) | ||
=> Wrap(_value.GetAncestor(n)); | ||
|
||
/// <summary> | ||
/// Gets the value of a descendant node that is greater than <paramref name="child1"/> and less than <paramref name="child2"/>. | ||
/// </summary> | ||
/// <param name="child1">The lower bound.</param> | ||
/// <param name="child2">The upper bound.</param> | ||
/// <returns>A <see cref="HierarchyId"/> value.</returns> | ||
public HierarchyId GetDescendant(HierarchyId child1, HierarchyId child2) | ||
=> Wrap(_value.GetDescendant(Unwrap(child1), Unwrap(child2))); | ||
|
||
/// <inheritdoc/> | ||
public override int GetHashCode() | ||
=> _value.GetHashCode(); | ||
|
||
/// <summary> | ||
/// Gets the level of this node in the hierarchical tree. | ||
/// </summary> | ||
/// <returns>The depth of this node. The root node is level 0.</returns> | ||
public short GetLevel() | ||
=> _value.GetLevel().Value; | ||
|
||
/// <summary> | ||
/// Gets a value representing the location of a new node that has a path from <paramref name="newRoot"/> equal to the path from <paramref name="oldRoot"/> to this, effectively moving this to the new location. | ||
/// </summary> | ||
/// <param name="oldRoot">An ancestor of this node specifying the endpoint of the path segment to be moved.</param> | ||
/// <param name="newRoot">The node that represents the new ancestor.</param> | ||
/// <returns>A <see cref="HierarchyId"/> value or null if <paramref name="oldRoot"/> or <paramref name="newRoot"/> is null.</returns> | ||
public HierarchyId GetReparentedValue(HierarchyId oldRoot, HierarchyId newRoot) | ||
=> Wrap(_value.GetReparentedValue(Unwrap(oldRoot), Unwrap(newRoot))); | ||
|
||
/// <summary> | ||
/// Gets a value indicating whether this node is a descendant of <paramref name="parent"/>. | ||
/// </summary> | ||
/// <param name="parent">The parent to test against.</param> | ||
/// <returns>True if this node is in the sub-tree rooted at <paramref name="parent"/>; otherwise false.</returns> | ||
public bool IsDescendantOf(HierarchyId parent) | ||
{ | ||
if (parent == null) | ||
return false; | ||
|
||
return _value.IsDescendantOf(parent._value).Value; | ||
} | ||
|
||
/// <inheritdoc/> | ||
public override string ToString() | ||
=> _value.ToString(); | ||
|
||
/// <summary> | ||
/// Evaluates whether two nodes are equal. | ||
/// </summary> | ||
/// <param name="hid1">The first node to compare.</param> | ||
/// <param name="hid2">The second node to compare.</param> | ||
/// <returns>True if <paramref name="hid1"/> and <paramref name="hid2"/> are equal; otherwise, false.</returns> | ||
public static bool operator ==(HierarchyId hid1, HierarchyId hid2) | ||
{ | ||
var sh1 = Unwrap(hid1); | ||
var sh2 = Unwrap(hid2); | ||
|
||
return sh1.IsNull == sh2.IsNull && sh1.CompareTo(sh2) == 0; | ||
} | ||
|
||
/// <summary> | ||
/// Evaluates whether two nodes are unequal. | ||
/// </summary> | ||
/// <param name="hid1">The first node to compare.</param> | ||
/// <param name="hid2">The second node to compare.</param> | ||
/// <returns>True if <paramref name="hid1"/> and <paramref name="hid2"/> are unequal; otherwise, false.</returns> | ||
public static bool operator !=(HierarchyId hid1, HierarchyId hid2) | ||
{ | ||
var sh1 = Unwrap(hid1); | ||
var sh2 = Unwrap(hid2); | ||
|
||
return sh1.IsNull != sh2.IsNull || sh1.CompareTo(sh2) != 0; | ||
} | ||
|
||
/// <summary> | ||
/// Evaluates whether one node is less than another. | ||
/// </summary> | ||
/// <param name="hid1">The first node to compare.</param> | ||
/// <param name="hid2">The second node to compare.</param> | ||
/// <returns>True if <paramref name="hid1"/> is less than <paramref name="hid2"/>; otherwise, false.</returns> | ||
public static bool operator <(HierarchyId hid1, HierarchyId hid2) | ||
{ | ||
var sh1 = Unwrap(hid1); | ||
var sh2 = Unwrap(hid2); | ||
|
||
return !sh1.IsNull && !sh2.IsNull && sh1.CompareTo(sh2) < 0; | ||
} | ||
|
||
/// <summary> | ||
/// Evaluates whether one node is greater than another. | ||
/// </summary> | ||
/// <param name="hid1">The first node to compare.</param> | ||
/// <param name="hid2">The second node to compare.</param> | ||
/// <returns>True if <paramref name="hid1"/> is greater than <paramref name="hid2"/>; otherwise, false.</returns> | ||
public static bool operator >(HierarchyId hid1, HierarchyId hid2) | ||
{ | ||
var sh1 = Unwrap(hid1); | ||
var sh2 = Unwrap(hid2); | ||
|
||
return !sh1.IsNull && !sh2.IsNull && sh1.CompareTo(sh2) > 0; | ||
} | ||
|
||
/// <summary> | ||
/// Evaluates whether one node is less than or equal to another. | ||
/// </summary> | ||
/// <param name="hid1">The first node to compare.</param> | ||
/// <param name="hid2">The second node to compare.</param> | ||
/// <returns>True if <paramref name="hid1"/> is less than or equal to <paramref name="hid2"/>; otherwise, false.</returns> | ||
public static bool operator <=(HierarchyId hid1, HierarchyId hid2) | ||
{ | ||
var sh1 = Unwrap(hid1); | ||
var sh2 = Unwrap(hid2); | ||
|
||
return !sh1.IsNull && !sh2.IsNull && sh1.CompareTo(sh2) <= 0; | ||
} | ||
|
||
/// <summary> | ||
/// Evaluates whether one node is greater than or equal to another. | ||
/// </summary> | ||
/// <param name="hid1">The first node to compare.</param> | ||
/// <param name="hid2">The second node to compare.</param> | ||
/// <returns>True if <paramref name="hid1"/> is greater than or equal to <paramref name="hid2"/>; otherwise, false.</returns> | ||
public static bool operator >=(HierarchyId hid1, HierarchyId hid2) | ||
{ | ||
var sh1 = Unwrap(hid1); | ||
var sh2 = Unwrap(hid2); | ||
|
||
return !sh1.IsNull && !sh2.IsNull && sh1.CompareTo(sh2) >= 0; | ||
} | ||
|
||
private static SqlHierarchyId Unwrap(HierarchyId value) | ||
=> value?._value ?? SqlHierarchyId.Null; | ||
|
||
private static HierarchyId Wrap(SqlHierarchyId value) | ||
=> value.IsNull ? null : new HierarchyId(value); | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
src/EFCore.SqlServer.HierarchyId/Design/SqlServerHierarchyIdDesignTimeServices.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
using Microsoft.EntityFrameworkCore.Design; | ||
using Microsoft.EntityFrameworkCore.Scaffolding; | ||
using Microsoft.EntityFrameworkCore.SqlServer.Scaffolding; | ||
using Microsoft.EntityFrameworkCore.SqlServer.Storage; | ||
using Microsoft.EntityFrameworkCore.Storage; | ||
using Microsoft.Extensions.DependencyInjection; | ||
|
||
namespace Microsoft.EntityFrameworkCore.SqlServer.Design | ||
{ | ||
/// <summary> | ||
/// Enables configuring design-time services. Tools will automatically discover implementations of this | ||
/// interface that are in the startup assembly. | ||
/// </summary> | ||
public class SqlServerHierarchyIdDesignTimeServices : IDesignTimeServices | ||
{ | ||
/// <summary> | ||
/// Configures design-time services. Use this method to override the default design-time services with your | ||
/// own implementations. | ||
/// </summary> | ||
/// <param name="serviceCollection"> The design-time service collection. </param> | ||
public virtual void ConfigureDesignTimeServices(IServiceCollection serviceCollection) | ||
{ | ||
serviceCollection | ||
.AddSingleton<IRelationalTypeMappingSourcePlugin, SqlServerHierarchyIdTypeMappingSourcePlugin>() | ||
.AddSingleton<IProviderCodeGeneratorPlugin, SqlServerHierarchyIdCodeGeneratorPlugin>(); | ||
} | ||
} | ||
} |
42 changes: 42 additions & 0 deletions
42
src/EFCore.SqlServer.HierarchyId/EFCore.SqlServer.HierarchyId.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net6.0</TargetFramework> | ||
<AssemblyName>EntityFrameworkCore.SqlServer.HierarchyId</AssemblyName> | ||
<RootNamespace>Microsoft.EntityFrameworkCore.SqlServer</RootNamespace> | ||
<Description>Adds hierarchyid support to the SQL Server EF Core provider</Description> | ||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> | ||
<GenerateDocumentationFile>true</GenerateDocumentationFile> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<None Include="build\**\*"> | ||
<Pack>True</Pack> | ||
<PackagePath>build</PackagePath> | ||
</None> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.0" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\EFCore.SqlServer.HierarchyId.Abstractions\EFCore.SqlServer.HierarchyId.Abstractions.csproj" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<Compile Update="Properties\Resources.Designer.cs"> | ||
<DesignTime>True</DesignTime> | ||
<AutoGen>True</AutoGen> | ||
<DependentUpon>Resources.resx</DependentUpon> | ||
</Compile> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<EmbeddedResource Update="Properties\Resources.resx"> | ||
<Generator>ResXFileCodeGenerator</Generator> | ||
<LastGenOutput>Resources.Designer.cs</LastGenOutput> | ||
</EmbeddedResource> | ||
</ItemGroup> | ||
|
||
</Project> |
29 changes: 29 additions & 0 deletions
29
...SqlServer.HierarchyId/Extensions/SqlServerHierarchyIdDbContextOptionsBuilderExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
using Microsoft.EntityFrameworkCore.Infrastructure; | ||
using Microsoft.EntityFrameworkCore.SqlServer.Infrastructure; | ||
|
||
namespace Microsoft.EntityFrameworkCore | ||
{ | ||
/// <summary> | ||
/// HierarchyId specific extension methods for <see cref="SqlServerDbContextOptionsBuilder"/>. | ||
/// </summary> | ||
public static class SqlServerHierarchyIdDbContextOptionsBuilderExtensions | ||
{ | ||
/// <summary> | ||
/// Enable HierarchyId mappings. | ||
/// </summary> | ||
/// <param name="optionsBuilder">The builder being used to configure SQL Server.</param> | ||
/// <returns>The options builder so that further configuration can be chained.</returns> | ||
public static SqlServerDbContextOptionsBuilder UseHierarchyId( | ||
this SqlServerDbContextOptionsBuilder optionsBuilder) | ||
{ | ||
var coreOptionsBuilder = ((IRelationalDbContextOptionsBuilderInfrastructure)optionsBuilder).OptionsBuilder; | ||
|
||
var extension = coreOptionsBuilder.Options.FindExtension<SqlServerHierarchyIdOptionsExtension>() | ||
?? new SqlServerHierarchyIdOptionsExtension(); | ||
|
||
((IDbContextOptionsBuilderInfrastructure)coreOptionsBuilder).AddOrUpdateExtension(extension); | ||
|
||
return optionsBuilder; | ||
} | ||
} | ||
} |
Oops, something went wrong.