System.ArgumentException:表类型参数必须具有有效的类型名称

问题描述 投票:0回答:4

我正在尝试将用户定义的表类型传递到 C# 中的查询中。

类型由 2 列定义(组织和子组织)

这就是我的代码的样子:

DataSet ds = new DataSet();
try
{

    DataTable FilteredOrgSubOrg = new DataTable("OrgSubOrgValueType");
    FilteredOrgSubOrg.Columns.Add("org", typeof(string));
    FilteredOrgSubOrg.Columns.Add("subOrg", typeof(string));
    FilteredOrgSubOrg.Rows.Add(org, orgsub);
    using (SqlConnection conn = new SqlConnection(cCon.getConn()))
    {
        using (SqlCommand cmd = conn.CreateCommand())
        {
            cmd.CommandText = 
                "select * from myTable ex where year = @year' and qtr = @qtr" +
                " and EXISTS(SELECT 1 FROM @OrgSubOrg tt  WHERE ex.org like tt.org" +
                " AND ex.orgsub = tt.suborg  )"+
                " order by ex.org,year, qtr DESC";
            // 2. set the command object so it knows
            // to execute a stored procedure

            // 3. add parameter to command, which
            // will be passed to the stored procedure
            cmd.Parameters.Add(new SqlParameter("@OrgSubOrg", FilteredOrgSubOrg));
            cmd.Parameters.Add(new SqlParameter("@year", year));
            cmd.Parameters.Add(new SqlParameter("@qtr", qtr));


            conn.Open();
            SqlDataAdapter sqlDA = new SqlDataAdapter();

            sqlDA.SelectCommand = cmd;
            sqlDA.Fill(ds);

        }
    }

我是否传递了错误的参数?

当我在 SQL Server 中这样做时:

declare @OrgSubOrg OrgSubOrgValueType
insert into @OrgSubOrg  values ('05%','00000000')
insert into @OrgSubOrg values ('03%','00000000')


------------ complete -----------------------------------
select * from myTable ex
where 
year = '2013' and qtr = '1' 
and EXISTS(
               SELECT 1 
               FROM @OrgSubOrg tt               
               WHERE ex.org like tt.org
                 AND ex.orgsub = tt.suborg  )
order by ex.org,year, qtr DESC

everything works like it should.

我也尝试过像这样传递它:

  SqlParameter p = cmd.Parameters.Add(new SqlParameter("@OrgSubOrg", SqlDbType.Structured));
                     p.Value = FilteredOrgSubOrg;

但我遇到了同样的错误

The table type parameter '@OrgSubOrg' must have a valid type name.

我是否无法将其传递给 SQL 命令,我在另一个地方有类似的代码,它与存储过程配合得很好...?

c# asp.net .net sql-server-2008
4个回答
84
投票

使用 TypeName 属性将映射设置为 SqlServer 中的类型:获取或设置必须修复的表值参数的类型名称。

p.TypeName = "dbo.MyType";

同时检查表值参数帖子


18
投票

请注意,当您执行存储过程并且没有将 SqlCommand.CommandType 设置为 CommandType.StoredProcedure 时,也可能会发生这种情况,如下所示:

using (SqlCommand cmd = new SqlCommand("StoredProcName", conn))
{
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.ExecuteNonQuery();
}

7
投票

当您想将表参数传递到存储过程时,您也可能会收到此错误。如果您使用实体模型Context.Database.SqlQuery(),就会发生这种情况。您必须为表参数设置 TypeName 属性。

SqlParameter codesParam = new SqlParameter(CODES_PARAM, SqlDbType.Structured);
            SqlParameter factoriesParam = new SqlParameter(FACTORIES_PARAM, SqlDbType.Structured);

            codesParam.Value = tbCodes;
            codesParam.TypeName = "[dbo].[MES_CodesType]";
            factoriesParam.Value = tbfactories;
            factoriesParam.TypeName = "[dbo].[MES_FactoriesType]";


            var list = _context.Database.SqlQuery<MESGoodsRemain>($"{SP_NAME} {CODES_PARAM}, {FACTORIES_PARAM}"
                , new SqlParameter[] {
                   codesParam,
                   factoriesParam
                }
                ).ToList();

0
投票

如果您不打算使用 TVP,则可以使用 JSON 格式的字符串,您可以通过 OPENJSON 函数将其传递并用作表。

示例:

MERGE SubscriptionAccess AS Target
USING OPENJSON(@frontendSubscriptions) WITH (ProductId INT, SubscriptionId INT, IsAccessGranted BIT) AS Source
ON Source.ProductId = Target.ProductId
AND Source.SubscriptionId = Target.SubscriptionId

我不想对数据库进行任何更改,因此为表变量创建类型对我来说是一个破坏者。

© www.soinside.com 2019 - 2024. All rights reserved.