Oleg's answer is correct, the hierarchy is still not very well integrated into EF, and you have to work with strings in .net. Here is another approach that has been used since the early days of the HierarchyId data type:
Stored Procedure:
CREATE PROCEDURE GetSomethingByNodeId @startingRoot hierarchyid,
END
In the application, you add a partial class for your EF data context with an SP call using the plain old ADO.NET. You will probably write it in another way or use Dapper instead, but the main idea here is to pass the parameter as a SQL Server string, and it will implicitly convert to HierarchyId:
public partial class TestEntities { public string GetSomethingByNodeId(string startingRoot) { using (var connection = new SqlConnection(this.Database.Connection.ConnectionString)) { var command = new SqlCommand("GetSomethingByNodeId", connection); command.CommandType = CommandType.StoredProcedure; command.Parameters.AddWithValue("@startingRoot", startingRoot); var outParameter = new SqlParameter("@return", SqlDbType.NVarChar, 500); outParameter.Direction = ParameterDirection.Output; command.Parameters.Add(outParameter); connection.Open(); command.ExecuteNonQuery(); return outParameter.Value.ToString(); } } }
Then call this method like any other stored procedure using your EF context:
using (var context = new TestEntities()) { var s = context.GetSomethingByNodeId("/1/1.3/"); }
UPD: this is how the extension method for an obsolete call to the HierarchyId procedure will look like with Dapper (it looks much better to me than regular ADO.NET):
public string GetSomethingByNodeId(string startingRoot) { using (var connection = new SqlConnection(this.Database.Connection.ConnectionString)) { var parameters = new DynamicParameters(); parameters.Add("startingRoot", startingRoot); parameters.Add("return", null, DbType.String, ParameterDirection.Output, 500); connection.Open(); connection.Execute("GetSomethingByNodeId", parameters, commandType: CommandType.StoredProcedure); return parameters.Get<string>("return"); } }
source share