使用Massive Insert我在尝试获取scope_identity()时得到DBNull

Ron*_*lev 2 sql c#-4.0 massive

我有一个带有标识列的表.
使用Massive和这样的代码

var table = new Categories();
var newID = table.Insert(new {CategoryName = "Buck Fify Stuff", Description = "Things I like"});
Run Code Online (Sandbox Code Playgroud)

然后

table.Scalar("select scope_identity()");
Run Code Online (Sandbox Code Playgroud)

返回DBNull :(

我需要做些什么才能获得实际插入的标识值

Cri*_*scu 5

MSDN文档声明SCOPE_IDENTITY:

"检索当前会话中任何表中生成的最后一个标识值"

查看Massive源代码,似乎每次调用都会Scalar()打开一个新连接:

/// <summary>
/// Returns a single result
/// </summary>
public virtual object Scalar(string sql, params object[] args) {
    object result = null;
    using (var conn = OpenConnection()) {            // <-- see this ...
        result = CreateCommand(sql, conn, args).ExecuteScalar();
    }
    return result;
}

...

/// <summary>
/// Returns and OpenConnection
/// </summary>
public virtual DbConnection OpenConnection() {
    var result = _factory.CreateConnection();
    result.ConnectionString = ConnectionString;
    result.Open();                                  // <-- ...and this 
    return result;
}
Run Code Online (Sandbox Code Playgroud)

因此,每次table.Scalar("select scope_identity()");执行此操作时,实际上都是在新连接中执行此操作(这意味着不同的会话/范围).

这解释了DBNull结果.

但既然你已经在做:

var newID = table.Insert(...)
Run Code Online (Sandbox Code Playgroud)

你可能想检查newID插入后的值; 我希望你能在那里找到一些不错的东西.

至少,这就是Insert()导致我相信的代码:

   public virtual dynamic Insert(object o) {
        var ex = o.ToExpando();
        if (!IsValid(ex)) {
            throw new InvalidOperationException("Can't insert: " + String.Join("; ", Errors.ToArray()));
        }
        if (BeforeSave(ex)) {
            using (dynamic conn = OpenConnection()) {
                var cmd = CreateInsertCommand(ex);
                cmd.Connection = conn;
                cmd.ExecuteNonQuery();
                cmd.CommandText = "SELECT @@IDENTITY as newID";
                ex.ID = cmd.ExecuteScalar();
                Inserted(ex);
            }
            return ex;
        } else {
            return null;
        }
    }
Run Code Online (Sandbox Code Playgroud)