HierarchyID与.net 5和EF Core抛出强制转换错误



我一开始就说,我不是一个"真正的"开发人员。我目前正在用一个自己喜欢的项目自学c#,我遇到了一个绊脚石,到目前为止,无论用多少谷歌搜索或书评都无济于事。我认识的几个有开发背景的人都耸耸肩,因为大多数人都是Java或类似的,而不是c#,而一个做c#的人仍然在使用以前的。net Core版本,从来没有在实体框架中做过任何事情。

对于我的项目,我使用。net Framework 5, EF Core 5.0.9和最新版本的SQL Server,我正在构建一个c# Web API。我确实加载了EntityFrameworkCore.SqlServer.HierarchyId库。Visual Studio识别HierarchyId数据类型没有任何问题,数据库和所有表通过迁移创建,所有表在另一边都有正确的列数据类型,所以我相当确定我至少有大部分我需要的东西。

在SQL Server端,我已经验证了我可以在指定的表中手动创建一个项目,并且HierarchyId和所有工作都如预期的那样。我有许多其他没有任何HierarchyId列的表,这些表的创建操作都可以正常工作。

尽管如此,每次我尝试创建一个新项目,或者用HierarchyId从表中查询一个现有项目时,我都会得到一个错误,说明

无法强制转换'System '类型的对象。Int16' to type 'System。字符串'

通过调试器中的步骤,我可以验证值是否正确生成(在本例中为/)并显示为类型Microsoft.EntityFrameworkCore.HierarchyId,并且我还没有达到我试图序列化任何东西以返回到客户端的地步,所以我不确定发生了什么。

使用的代码非常简单(稍微一般化):

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

与create一样,在调试器中显示返回的项具有所有正确的属性和值,但它仍然会爆炸。日志内容,无论其价值如何,都包含在下面以供参考(与上面类似,但其他方面不变)。最后一行是我转储到日志的东西,因为这是我在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.RepoRepositoryManager.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

有人能帮忙吗?

无法强制转换类型为'System '的对象。Int16' to type 'System。字符串'

也许表中的列类型与myTableItem类中的类型不相同。试着检查你的myTableItem类和表,myTableItem类中的类型是int,而在表中是string。

最新更新