5

我最近一直在使用dapper,除了使用表变量之外,总的来说没有任何问题。

为了演示,我使用了这个线程中的一个修改示例。

此代码可以正常工作:

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”。

我的使用有什么问题吗,或者这是dapper 中的错误/缺失功能?

最好的问候, Kc


更新:

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

更多背景信息:

我真正想做的是:

  • 将 Id 列表插入索引表变量(或者如果表变量不起作用,则可能是临时表)
  • 针对我的一个持久表加入这个表并返回结果。

我的目的是在使用 WHERE IN (...) 子句从我的表中进行 SELECT 时解决性能问题

4

3 回答 3

5

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

DECLARE @t TABLE (
   -- table definition
);
于 2014-10-06T17:41:11.057 回答
2

你说:

我的目的是在使用 WHERE IN (...) 子句从我的表中进行 SELECT 时解决性能问题

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

似乎对我有用的是DataTable在 C# 中创建一个并将其传递给 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;
        }
于 2017-05-24T19:07:32.673 回答
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"}
});
于 2014-01-11T09:57:33.187 回答