Search code examples
sqlc#-4.0massive

Using Massive Insert I get DBNull when trying to get scope_identity()


I have a table with an identity column.
Using Massive with code like this

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

then

table.Scalar("select scope_identity()");

returns DBNull :(

What do I need to do different to get the actual inserted identity value


Solution

  • The MSDN documentation states that SCOPE_IDENTITY:

    "retrieves the last identity values that are generated in any table in the current session"

    Looking at the Massive source code, it appears that every call to Scalar() opens a new connection:

    /// <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;
    }
    

    Therefore, every time you are doing table.Scalar("select scope_identity()"); you are actually doing this in a new connection (which means a different session/scope).

    This explains the DBNull result.

    But since you are already doing:

    var newID = table.Insert(...)
    

    you might want to inspect the value of newID after the insert happens; I hope you'll find something nice in there.

    At least, that's what the code for Insert() leads me to believe:

       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;
            }
        }