2013-02-25 76 views
2

我有一個帶有標識列的表。
使用厚重,這樣的代碼使用大規模插入我試圖獲得scope_identity時得到DBNull()

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

然後

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

返回DBNull :(

什麼我需要做的不同,以獲得實際插入的標識值

+2

你得到NEWID的table.insert語句後什麼樣的價值?基於應該是識別值的文檔。 – JeffO 2013-02-25 20:44:11

回答

5

的MSDN文檔指出SCOPE_IDENTITY

「可檢索任何表產生在當前會話中的最後一個標識值」

望着Massive source code,似乎到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; 
     } 
    } 
+0

沒錯。在你的例子中'newID.ID'將具有標識值。謝謝!!! – 2013-02-25 20:48:58