【问题标题】:Using Dapper.TVP TableValueParameter with other parameters将 Dapper.TVP TableValueParameter 与其他参数一起使用
【发布时间】:2014-10-07 18:07:00
【问题描述】:

我有一个接收表值参数的过程以及其他过程:

CREATE PROCEDURE [dbo].[Update_Records]
    @currentYear INT,
    @country INT,
    @records Record_Table_Type READONLY
AS

我正在尝试使用 Dapper.TVP 来调用它。

这是我目前的代码:

        var recordsParameter = new List<SqlDataRecord>();

        // This metadata matches 'Record_Table_Type' in the Database
        var recordsMetaData = new[]
        {
            new SqlMetaData("OriginalValue", SqlDbType.Decimal, 19, 4),
            new SqlMetaData("NewValue", SqlDbType.Decimal, 19, 4),
            new SqlMetaData("NewPercent", SqlDbType.Decimal, 7, 2),
        };

        foreach (var r in records)
        {
            var record = new SqlDataRecord(recordsMetaData);
            record.SetDecimal(0, r.OriginalValue);
            record.SetDecimal(1, r.NewValue);
            record.SetDecimal(2, r.NewPercent);
            recordsParameter.Add(record);
        }

        var spParams = new DynamicParameters(new
        {
            currentYear = filter.currentYear,
            country = filter.country,
        });

        var recordsParam = new TableValueParameter("@records", "Record_Table_Type", recordsParameter);

        using (var connection = ConnectionFactory.GetConnection())
        {
            connection.Execute("Update_Records", ???, commandType: CommandType.StoredProcedure);
        }

我的问题是如何将两组参数传递给调用 Dapper Execute() 的过程?

我试过了:

var spParams = new DynamicParameters(new
{
    currentYear = filter.currentYear,
    country = filter.country,
    records = new TableValueParameter("@records", "Record_Table_Type", recordsParameter);
});

connection.Execute("Update_Records", spParams, commandType: CommandType.StoredProcedure);

connection.Execute("Update_Records", new Object[] { spParams, recordsParam }, commandType: CommandType.StoredProcedure);

两者都调用过程,但传递一个空表参数(SELECT COUNT(*) FROM @records 返回 0)

我似乎找不到 Dapper.TVP 的任何实际文档或来源,所以整个事情非常混乱,.Execute() 的第二个参数只是一个dynamic,所以再次没有告诉我我能传递给它的,不能传递给它的。

有什么想法吗?

【问题讨论】:

标签: c# sql-server dapper


【解决方案1】:

我在移动设备上,可能会误解这个问题,但这应该只是:

DataTable records = ...
connection.Execute("Update_Records",
    new {
        currentYear = filter.currentYear,
        country = filter.country,
        records
    },
    commandType: CommandType.StoredProcedure
);

【讨论】:

  • 是的,这就是我最终所做的。我最初的搜索出现了 Dapper.TVP NuGet 包,它似乎不再需要(或维护?)。谢谢!
  • @CodingWithSpike 确实,不再需要它 - dapper 在内部处理 TVP;至于维护:我不知道 - 这不是我的;p
【解决方案2】:

根据 Mark Gravell 的回答:Does Dapper support SQL 2008 Table-Valued Parameters?

我更改了我的代码,不再使用 Dapper.TVP,而是使用 DataTable,所以现在的代码是:

        var recordsTable = new DataTable();
        recordsTable.Columns.Add("NewValue", typeof(Decimal));
        foreach (var netRevenue in records)
        {
            var row = recordsTable.NewRow();
            row[0] = netRevenue.NewValue;
            recordsTable.Rows.Add(row);
        }
        recordsTable.EndLoadData();

        var spParams = new DynamicParameters(new
        {
            currentYear = filter.currentYear,
            country = filter.country,
            records = recordsTable.AsTableValuedParameter("Record_Table_Type")
        });

        using (var connection = ConnectionFactory.GetConnection())
        {
            connection.Execute("Update_Records", spParams, commandType: CommandType.StoredProcedure);
        }

这行得通。

【讨论】:

  • 你实际上不应该在这里需要 As...:因为 sproc 定义了用户定义的类型,它应该可以在不指定的情况下工作。
  • 如果您使用的是动态 SQL,请执行此操作。
猜你喜欢
  • 2014-03-23
  • 2021-11-22
  • 2015-06-06
  • 1970-01-01
  • 2021-07-26
  • 2017-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多