Dapper:将行插入表变量

时间:2014-01-11 09:30:15

标签: c# sql insert dapper table-variable

我最近一直在使用 dapper ,除了使用表变量外,所有这些都没有问题。

为了演示,我使用this thread中的修改示例。

此代码可以正常运行:

int tally = connection.Execute(
    "create table #t(Name nvarchar(max), Age int)\n" +
    "insert #t (Name,Age) values(@Name, @Age)", new[]
    {
        new {Age = 1, Name = "sam"},
        new {Age = 2, Name = "bob"}
    });

但这不是:

int tally = connection.Execute(
    "create table @t(Name nvarchar(max), Age int)\n" +
    "insert @t (Name,Age) values(@Name, @Age)", new[]
    {
        new {Age = 1, Name = "sam"},
        new {Age = 2, Name = "bob"}
    });

唯一的变化是使用表变量而不是临时表(@ instead #)。 Dapper(或链中的任何其他东西?)似乎以某种方式将它与参数混合并返回“必须声明表变量@t”。

我的使用方法有什么问题,或者这是短小精悍的错误/缺失功能?

祝你好运, KC


更新:

只是为了澄清:@t不是dapper设置的参数。 @t被声明为本地表,该表仅存在于当前运行的查询中。在我看来,dapper不应该区分任何类型的表,无论是“普通”表,本地/全局临时表还是表变量。

更多背景信息:

我真正想做的是:

  • 将Ids列表插入索引表变量(如果表变量不起作用,则可能是临时表)
  • 将此表连接到我的一个持久表并返回结果。

我的目的是在从带有WHERE IN(...)子句的表中选择

时解决性能问题

3 个答案:

答案 0 :(得分:4)

如果您使用的是SQL Server,则语法不正确。在SQL Server中,表变量的创建方式与常规表的创建方式不同。它应该是这样的:

DECLARE @t TABLE (
   -- table definition
);

答案 1 :(得分:1)

你错了。 Dapper和所有其他micro-Orms不关心任何sql风格所定义的表变量,它们只关心sql参数。

你应该这样做(假设表名不是来自用户输入 - 为什么要这样?!)

var tableName='my_table' ;
int tally = connection.Execute(
string.format("create table {0}(Name nvarchar(max), Age int)\n" +
"insert {0} (Name,Age) values(@Name, @Age)",tableName), new[]
{
    new {Age = 1, Name = "sam"},
    new {Age = 2, Name = "bob"}
});

答案 2 :(得分:0)

你说:

  

我的目的是在从我的选择中击败性能问题   具有WHERE IN(...)子句的表

我也担心表现。我有一个巨大的表,每次查询时都需要选择一小部分。

对我来说似乎有用的是在C#中创建DataTable并将其传递给Dapper的AsTableValuedParameter方法。然后我会:

  

将此表连接到我的一个持久表并返回   结果

如,

首先在我的数据库中创建了一个UDTT:

 CREATE TYPE [dbo].[IDs] AS TABLE(
    [ID] [int] NOT NULL,
    PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)

然后在我的代码中创建一个DataTable:

        var dt = new DataTable();
        dt.Columns.Add(new DataColumn("Id", typeof(long)));

//i'm adding from a list passed as parameter; your example is via collection initializer
        foreach (var id in Ids)
        {
            dt.Rows.Add(id);
        }

然后编写一个将大表连接到我的子集的查询:

        using (IDbConnection sqlConnection = new SqlConnection(connectionString))
        {

            const string query = @"

SELECT *
FROM [dbo].[Candidate] c
JOIN @tvp t ON c.CandidateID = t.ID

";
            var candList = sqlConnection.Query<Candidate>(query, new { tvp = dt.AsTableValuedParameter("[dbo].[IDs]") }).ToList();

            return candList;
        }