Используя Massive Insert, я получаю DBNull при попытке получить scope_identity()

У меня есть таблица со столбцом идентификаторов.
Использование Massive с таким кодом

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

тогда

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

возвращает DBNull :(

Что мне нужно сделать по-другому, чтобы получить фактическое вставленное значение идентификатора


person Ron Harlev    schedule 25.02.2013    source источник
comment
Какое значение вы получите для newID после оператора table.insert? Согласно документации, это должно быть значением идентификации.   -  person JeffO    schedule 26.02.2013


Ответы (1)


В документации 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;
}

Следовательно, каждый раз, когда вы делаете table.Scalar("select scope_identity()");, вы фактически делаете это в новом соединении (что означает другой сеанс/область действия).

Это объясняет результат DBNull.

Но так как вы уже делаете:

var newID = table.Insert(...)

вы можете проверить значение 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;
        }
    }
person Cristian Lupascu    schedule 25.02.2013