Dapper + MSAccess:如何获取插入行的标识符

时间:2016-05-23 13:08:22

标签: c# ms-access dapper

我正在使用Dapper和C#,后端是MS Access。我的DAL方法在数据库中插入记录。我想返回插入行的唯一标识符(或带有唯一标识符的更新POCO)。 我期待我的功能如下(我知道这不起作用;只是为了解释我想要的东西): -

public MyPoco Insert(MyPoco myPoco)
{
    sql = @"INSERT INTO MyTable (Field1, Field2) VALUES (@Field1, @Field2)";
    var param = GetMappedParams(myPoco);//ID property here is null.
    var result = _connection.Query<MyPoco>(sql, param, null, false, null, CommandType.Text);.Single();
    return result;//This result now contains ID that is created by database.
}

我来自NHibernate世界,POCO自动更新NH。如果不;我们可以调用Refresh方法并更新ID。 我不知道如何用Dapper实现这一目标。

我在SO上阅读了this的问题,因为它与SQL Server有关。

另一个this问题尚未接受答案。

我看了this问题,其中接受的答案解释了使用@@Identity的陷阱。

2 个答案:

答案 0 :(得分:3)

这对我有用:

static MyPoco Insert(MyPoco myPoco)
{
    string sql = "INSERT INTO MyTable (Field1, Field2) VALUES (@Field1, @Field2)";
    _connection.Execute(sql, new {myPoco.Field1, myPoco.Field2});
    myPoco.ID = _connection.Query<int>("SELECT @@IDENTITY").Single();
    return myPoco;  // This result now contains ID that is created by database.
}

请注意,这适用于Access数据库的OleDbConnection,但它 不能与OdbcConnection一起使用。

编辑重新评论

为确保INSERT和SELECT调用之间的Connection保持打开状态,我们可以这样做:

static void Insert(MyPoco myPoco)
{
    string sql = "INSERT INTO MyTable (Field1, Field2) VALUES (@Field1, @Field2)";
    bool connAlreadyOpen = (_connection.State == System.Data.ConnectionState.Open);
    if (!connAlreadyOpen)
    {
        _connection.Open();
    }
    _connection.Execute(sql, new {myPoco.Field1, myPoco.Field2});
    myPoco.ID = _connection.Query<int>("SELECT @@IDENTITY").Single();
    if (!connAlreadyOpen)
    {
        _connection.Close();
    }
    return;  // (myPoco now contains ID that is created by database.)
}

答案 1 :(得分:1)

还有一些额外的想法:如果@@Identity pitfalls是一个问题,那么另一个选择是在代码中提前创建一个新的GUID,然后将该GUID与其余数据一起插入,而不是让它Access在创建新记录时创建标识值。

我很感激,只有在您的特定情况允许表的GUID主键时,它才会起作用,但它确实保证您知道刚刚插入的记录的键的真值。

或者,如果您不想要GUID键,则可以创建一个包含单行的表,该行包含应用程序中任何手动管理的键的当前种子值。然后,您可以在每次要插入新记录时手动递增特定种子的值。与GUID方法一样,您将手动插入带有记录的ID,这次ID将是您刚刚检索到的新增加的种子。

同样,这应该保证每个插入的唯一键,尽管现在你正在为每个插入执行读取和两次写入。