如何使用'hierarchyid'参数从EntityFramework 6调用存储过程

Sho*_*yga 5 sql-server stored-procedures entity-framework hierarchyid entity-framework-6

我正在使用WebApi2和EntityFramework6开发服务.我有一个我的服务必须使用的遗留SQLServer数据库.

该DB大量使用'hierarchyid'数据类型,此类型在DB的存储过程内部使用.

好像EF6不支持'hierarchyid'数据类型,所以我使用这个fork来增加对'hierarchyid'的支持.

虽然从DB中检索到的是'hierarchyid'类型,但我的问题在于存储过程需要'hierarchyid'作为参数.

存储过程如下所示:

CREATE PROCEDURE [dbo].[GetSomethingByNodeId]
    (
        @startingRoot HIERARCHYID
        ,@return HIERARCHYID OUTPUT
    )
Run Code Online (Sandbox Code Playgroud)

我调用此存储过程的客户端代码如下所示:

var param1 = new SqlParameter("@startingRoot", new HierarchyId("/"));
var param2 = new SqlParameter{ ParameterName = "@return", Value = 0, Direction = ParameterDirection.Output };

var obj = context.Database.SqlQuery<HierarchyId>("GetSomethingByNodeId" @startingRoot, @return out", param1, param2).ToList();
Run Code Online (Sandbox Code Playgroud)

但不幸的是,调用此查询会抛出一个异常,说:

An unhandled exception of type 'System.ArgumentException' occurred in EntityFramework.SqlServer.dll

Additional information: No mapping exists from object type System.Data.Entity.Hierarchy.HierarchyId to a known managed provider native type.
Run Code Online (Sandbox Code Playgroud)

关于我如何使这项工作的任何想法?

Ole*_*now 3

不幸的是,MetaType.GetMetaTypeFromValue 不允许添加类型(所有支持的类型都是硬编码的)。我认为您可以使用 nvarchar 参数和转换来实现您的目标。

在您的 C# 代码中:

var param1 = new SqlParameter("@startingRoot", "/1/");
var param2 = new SqlParameter { ParameterName = "@return", Value = "", Size = 1000, Direction = ParameterDirection.Output };

var ids = context.Database.SqlQuery<HierarchyId>("GetSomethingByNodeId @startingRoot, @return out", param1, param2).ToList();
var returnedId = new HierarchyId(param2.Value.ToString());
Run Code Online (Sandbox Code Playgroud)

在你的程序中(我在里面写了一些测试代码):

CREATE PROCEDURE [dbo].[GetSomethingByNodeId]
    (
        @startingRoot nvarchar(max), @return nvarchar(max) OUTPUT
    )
as 
declare @hid hierarchyid = hierarchyid::Parse('/1/')
select @return = @hid.ToString()

declare @root hierarchyid = hierarchyid::Parse(@startingRoot)
select @root as field
Run Code Online (Sandbox Code Playgroud)

另外,您可以尝试使用Microsoft.SqlServer.Types和 SqlHierarchyId 类型,如下所示:

var sqlHierarchyId = SqlHierarchyId.Parse("/");
var param1 = new SqlParameter("@startingRoot", sqlHierarchyId) { UdtTypeName = "HierarchyId" };
Run Code Online (Sandbox Code Playgroud)

但是,我认为,这是错误的方向。