找不到CLR类型'Int32 []'到关系类型的映射 [英] No mapping to a relational type can be found for the CLR type 'Int32[]'

查看:184
本文介绍了找不到CLR类型'Int32 []'到关系类型的映射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我在ASP.NET Core项目中从Entity Framework Core(v2.0)执行SQL Server存储过程时,出现此异常:

When I execute a SQL Server stored procedure from Entity Framework Core (v2.0) in my ASP.NET Core project, I get this exception:


InvalidOperationException:找不到CLR类型'Int32 []'的关系类型映射

InvalidOperationException: no mapping to a relational type can be found for the CLR type 'Int32[]'

SQL服务器存储过程代码如下:

The SQL Server stored procedure code looks like this:

CREATE PROCEDURE [dbo].[sp-UpdateProductOrderAndStock]
    @customerOrderID INT,
    @qty INT
AS
    DECLARE @customerProductID INT
    SET @customerProductID = (SELECT CustomerProductID 
                              FROM dbo.CustomerOrder 
                              WHERE ID = @customerOrderID)

    SET NOCOUNT ON;  

    UPDATE dbo.CustomerOrder
    SET CompletedQty = CompletedQty + @qty
    WHERE ID = @customerOrderID;

    UPDATE dbo.CProductStation
    SET Qty = Qty - @qty
    WHERE CustomerProductID = @customerProductID AND StationNo = 0;

ASP.NET Core数据模型如下:

ASP.NET Core data model as below:

public class CustomerProductDelivery
{
    public int ID { get; set; }
    public int CustomerOrderID { get; set; }
    public DateTime DeliveryDate { get; set; }
    public string DeliveryNo { get; set; }
    public int DeliveryQty { get; set; }
    public CustomerOrder CustomerOrder { get; set; }
}

ASP.net核心执行存储过程的控制器代码:

ASP.net core Controller code to execute the stored procedure:

_context.Database.ExecuteSqlCommand("sp-UpdateProductOrderAndStock @p0, @p1", parameters: new[] { customerProductDelivery.CustomerOrderID,customerProductDelivery.DeliveryQty });


推荐答案

TLDR

使用字符串插值

_context.Database.ExecuteSqlCommand($"Update_ProductOrderAndStock {customerProductDelivery.CustomerOrderID}, {customerProductDelivery.DeliveryQty}");

详细答案:

您正在陷入典型的 params对象[] 陷阱。

You are falling into a typical params object[] trap.

首先,让我们看看表达式的类型

First, let see what's the type of the expression

var parameters = new[] { customerProductDelivery.CustomerOrderID,customerProductDelivery.DeliveryQty }

由于两个元素的类型均为 int ,因此推断的类型为 int []

Since both elements are of type int, the inferred type is int[].

现在,有2个 ExecuteSqlCommand 方法重载其中允许您分别传递参数-一个接收 params object [] ,第二个接收 IEnumerable< object>

Now, there are 2 ExecuteSqlCommand method overloads which allow you to pass parameters separately - one receiving params object[] and second receiving IEnumerable<object>.

尽管 IEnumerable< T> 是协变的,但协变不适用于值类型,因此 IEnumerable< int> 不能被视为 IEnumerable< object> ,因此第二个重载不匹配。

Although IEnumerable<T> is covariant, covariance does not work for value types, so IEnumerable<int> cannot be treated as IEnumerable<object>, hence the second overload does not match.

因此唯一有效的重载是接收 params对象[] 的重载。但是由于 int [] 无法转换为 object [] ,因此编译器将其视为 object ,从而发出类似于 new object [] {parameters} 的东西。

So the only valid overload is the one receiving params object[]. But since int[] cannot be cast to object[], the compiler treats it as single object, thus emitting something like new object[] { parameters }.

最终结果是,EF方法接收到类型值为 int [] 的单个参数,并生成有问题的异常。

The net effect is that the EF method receives single parameter with int[] type value and generates the exception in question.

话虽这么说,它可以通过多种方式解决。

With that being said, it could be fixed in many ways.

一种是删除 new [] {} ,这是 params对象[] 构造的整体思想:

One is to remove new [] { } from the call, which is the whole idea of params object[] construct:

_context.Database.ExecuteSqlCommand(
    "Update_ProductOrderAndStock @p0, @p1", customerProductDelivery.CustomerOrderID, customerProductDelivery.DeliveryQty);

另一种是替换 new [] 与显式的 new对象[]

Another is to replace the new [] with the explicit new object[].

另一种方法是利用EF Core引入的 FromSql和ExecuteSqlCommand中的字符串插值

Yet another one is to utilize the EF Core introduced String interpolation in FromSql and ExecuteSqlCommand:

_context.Database.ExecuteSqlCommand(
    $"Update_ProductOrderAndStock {customerProductDelivery.CustomerOrderID}, {customerProductDelivery.DeliveryQty}");

这篇关于找不到CLR类型'Int32 []'到关系类型的映射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆