如何强制ADO.NET尊重表值参数的DEFAULT约束?

时间:2014-09-13 22:08:34

标签: c# sql-server tsql ado.net

我有一个带有DEFAULT约束的表类型:

CREATE TYPE dbo.T_MY_TABLE_TYPE AS TABLE 
(
    ID INT NOT NULL PRIMARY KEY,
    VALUE VARCHAR(64) NULL DEFAULT ''
)

我使用type作为我的存储过程的输入参数:

CREATE PROCEDURE USP_MY_PROCEDURE
(
    @P1 T_MY_TABLE_TYPE READONLY
)
AS
BEGIN
    SELECT * FROM @P1
END

在T-SQL中,我可以通过以下方式运行SP:

declare @p1 dbo.T_MY_TABLE_TYPE;
insert into @p1 values(1, default);
insert into @p1 values(2, NULL);
insert into @p1 values(3, 'abc');

exec dbo.USP_MY_PROCEDURE @P1 = @p1;

如何从ADO.NET生成相同的脚本?我尝试了以下代码:

public void MyMethod(List<string> input)
{
    using (SqlConnection con = GetConection())
    {
        using (var cmd = new SqlCommand("USP_MY_PROCEDURE", con))
        {
            cmd.CommandType = CommandType.StoredProcedure;
            AddTableParameter(cmd.Parameters, input);
            cmd.Connection.Open();

            using (IDataReader dataReader = cmd.ExecuteReader())
            {
                //...
            }
        }
    }
}

private void AddTableParameter(SqlParameterCollection sqlParameters, IEnumerable<string> input)
{
    SqlMetaData[] metaData =
    {
        new SqlMetaData("ID", SqlDbType.Int, false, true, SortOrder.Ascending, 0),
        new SqlMetaData("VALUE", SqlDbType.VarChar, 64)
    };

    int i = 1;

    var param = new SqlParameter("@P1", SqlDbType.Structured)
    {
        TypeName = "T_MY_TABLE_TYPE",

        Value = input.Select(s =>
        {
            var record = new SqlDataRecord(metaData);
            record.SetInt32(0, i++);

            if (s == null)
                record.SetDBNull(1);
            else if (s == "default")
            {
                //Do nothing. Expect that DEFAULT constraint of T_MY_TABLE_TYPE inserts ''. BUT IT DOES NOT HAPPEN!.
            }
            else
                record.SetString(1, s);

            return record;
        })
    };

    sqlParameters.Add(param);
}

但是,当我运行以下代码时:

    new MyTest().MyMethod(new List<string> { "default", null, "abc" });

代码生成的脚本忽略DEFAULT约束:

declare @p1 dbo.T_MY_TABLE_TYPE
insert into @p1 values(1, NULL) --This line is wrong!
insert into @p1 values(2, NULL)
insert into @p1 values(3, 'abc')

exec USP_MY_PROCEDURE @P1 = @p1

我尝试通过替换此行来使用SqlMetaData.UseServerDefault属性:

new SqlMetaData("VALUE", SqlDbType.VarChar, 64)

这一行:

new SqlMetaData("VALUE", SqlDbType.VarChar, 64, true, false, SortOrder.Unspecified, -1)

但似乎当我将useServerDefault参数指定为true时,SQL Server会忽略我为该列设置的任何值,但始终将列设置为其默认值。结果如下:

declare @p1 dbo.T_MY_TABLE_TYPE
insert into @p1 values(1, default)
insert into @p1 values(2, default)
insert into @p1 values(3, default)

exec USP_MY_PROCEDURE @P1 = @p1

有什么想法吗?

0 个答案:

没有答案