.NET 5 和 EF Core 的 HierarchyID 抛出转换错误

HierarchyID with .NET 5 and EF Core throws cast error

我会在开始时直截了当地说我不是 'real' 开发人员。我目前正在使用一个宠物项目自学 C#,但我遇到了一个绊脚石,到目前为止,无论使用多少谷歌搜索或书评都无济于事。我认识的少数具有开发背景的人几乎像大多数人那样耸了耸肩 Java 或类似的东西,而不是 C#,而使用 C# 的人仍在使用 .NET Core 的先前版本并且从未在 Entity Framework.

做过任何事情

对于我的项目,我正在使用 .NET Framework 5、EF Core 5.0.9 和最新版本的 SQL 服务器,并且我正在构建一个 C# Web API。我确实加载了 EntityFrameworkCore.SqlServer.HierarchyId 库。 Visual Studio 可以毫无问题地识别 HierarchyId 数据类型,并且数据库和所有 table 都是通过迁移创建的,所有 table 都具有正确的列数据类型另一方面,所以我相当确定我至少拥有我需要的大部分内容。

在 SQL 服务器端,我已验证我可以在指定的 table 中手动创建项目,并且 HierarchyId 和所有工作都按预期进行。我有许多其他 table 没有任何 HierarchyId 列,并且为这些创建操作都可以正常工作。

尽管如此,每次我尝试创建新项目,或使用 HierarchyId 从 table 查询现有项目时,我都会收到一条错误消息

Unable to cast object of type 'System.Int16' to type 'System.String'

通过调试器中的步骤,我可以验证该值是否正确生成(在本例中为 /)并显示为 Microsoft.EntityFrameworkCore.HierarchyId 类型,但我还没有达到我正在尝试的地步尚未将任何内容序列化到 return 给客户端,所以我不确定发生了什么。

使用的代码很简单(略有概括):

var entity = new myTableItem
{
     myItemName = myItem.Name,
     myItemDescription = myItem.Description,
     myItemHierarchyId = HierarchyId.GetRoot()
}

myContext.add(entity);
myContext.save();

一到达Add,它就会爆炸并提供先前指定的错误。我还尝试过手动创建一个根,然后尝试通过它的 ID(DB Id 不是 HierarchyId)检索根条目,这样我就可以尝试添加一个子节点,但是一旦查询运行,我就会得到同样的错误,它不会再继续下去(这就是我确定它是 HierarchyId 列的方式)。作为参考,我用来检索根条目的代码如下:

parentItem = myContext.myTableItems.FirstorDefault(x => x.myItemId == myItem.myItemId).myItemHierarchyId

与创建一样,遍历调试器会显示一个项目 returned 具有所有正确的属性和值,非常漂亮,但它仍然会爆炸。日志内容,无论其价值如何,都包含在下面以供参考(概括与上述类似,但其他内容不变)。最后一行是我要转储到日志中的内容,因为这就是我一直使用 PowerShell 执行此操作的方式,因为我今天早上才刚刚学会如何使用调试器执行基于操作的操作,但它显示我拥有数据和正确的数据类型。

2021-09-13 12:28:54.0063 ERROR Something went wrong: Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details.
 ---> System.InvalidCastException: Unable to cast object of type 'System.Int16' to type 'System.String'.
   at Microsoft.Data.SqlClient.SqlBuffer.get_String()
   at Microsoft.Data.SqlClient.SqlDataReader.GetString(Int32 i)
   at lambda_method260(Closure , DbDataReader )
   at Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.ConsumeResultSetWithPropagation(Int32 commandIndex, RelationalDataReader reader)
   at Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.Consume(RelationalDataReader reader)
   --- End of inner exception stack trace ---
   at Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.Consume(RelationalDataReader reader)
   at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.Execute(IRelationalConnection connection)
   at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(IEnumerable`1 commandBatches, IRelationalConnection connection)
   at Microsoft.EntityFrameworkCore.Storage.RelationalDatabase.SaveChanges(IList`1 entries)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(IList`1 entriesToSave)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(DbContext _, Boolean acceptAllChangesOnSuccess)
   at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(Boolean acceptAllChangesOnSuccess)
   at Microsoft.EntityFrameworkCore.DbContext.SaveChanges(Boolean acceptAllChangesOnSuccess)
   at Microsoft.EntityFrameworkCore.DbContext.SaveChanges()
   at MyProject.Repo.RepositoryManager.Save() in ..MyProject.Repo\RepositoryManager.cs:line 155
   at MyProcjet.API.Controllers.MyItemsController.NewMyItem(MyItemCreateDto MyItem) in ..MyItemsController.cs:line 181
   at lambda_method3(Closure , Object , Object[] )
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync()
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)
2021-09-13 14:39:57.2496 INFO var myItemHierarchyId:/; Type: Microsoft.EntityFrameworkCore.HierarchyId

有人能帮忙吗?

Unable to cast object of type 'System.Int16' to type 'System.String'

也许您的 table 中的列类型与您的 myTableItem class.Try 中的类型不同,请检查您的 myTableItem class 和table,myTableItemclass中的类型是int,table中的是string。