SCOPE_IDENTITY无法在asp.net中运行?

我试图通过逐个执行两个查询来插入记录并获取其新生成的id,但不知道为什么它给我以下错误。

Object cannot be cast from DBNull to other types 

我的代码如下:(我不想使用sql存储过程)

 SqlParameter sqlParam; int lastInsertedVideoId = 0; using (SqlConnection Conn = new SqlConnection(ObjUtils._ConnString)) { Conn.Open(); using (SqlCommand sqlCmd = Conn.CreateCommand()) { string sqlInsertValues = "@Name,@Slug"; string sqlColumnNames = "[Name],[Slug]"; string sqlQuery = "INSERT INTO videos(" + sqlColumnNames + ") VALUES(" + sqlInsertValues + ");"; sqlCmd.CommandText = sqlQuery; sqlCmd.CommandType = CommandType.Text; sqlParam = sqlCmd.Parameters.Add("@Name", SqlDbType.VarChar); sqlParam.Value = txtName.Text.Trim(); sqlParam = sqlCmd.Parameters.Add("@Slug", SqlDbType.VarChar); sqlParam.Value = txtSlug.Text.Trim(); sqlCmd.ExecuteNonQuery(); //getting last inserted video id sqlCmd.CommandText = "SELECT SCOPE_IDENTITY() AS [lastInsertedVideoId]"; using (SqlDataReader sqlDr = sqlCmd.ExecuteReader()) { sqlDr.Read(); lastInsertedVideoId = Convert.ToInt32(sqlDr["lastInsertedVideoId"]); } } } //tags insertion into tag table if (txtTags.Text.Trim().Length > 0 && lastInsertedVideoId > 0) { string sqlBulkTagInsert = ""; string[] tags = txtTags.Text.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); foreach (string tag in tags) { sqlBulkTagInsert += "INSERT INTO tags(VideoId, Tag) VALUES(" + lastInsertedVideoId + ", " + tag.Trim().ToLowerInvariant()+ "); "; } using (SqlConnection Conn = new SqlConnection(ObjUtils._ConnString)) { Conn.Open(); using (SqlCommand sqlCmd = Conn.CreateCommand()) { string sqlQuery = sqlBulkTagInsert; sqlCmd.CommandText = sqlQuery; sqlCmd.CommandType = CommandType.Text; sqlCmd.ExecuteNonQuery(); } } } 

如果可能的话,请检查以上代码编码是否正确,或者我们可以进一步优化它以提高性能?

谢谢

对SCOPE_IDENTITY()的调用不会被视为与您正在执行的INSERT命令位于相同的“范围”中。

基本上,您需要做的是更改线路:

 string sqlQuery = "INSERT INTO videos(" + sqlColumnNames + ") VALUES(" + sqlInsertValues + ");"; 

至:

 string sqlQuery = "INSERT INTO videos(" + sqlColumnNames + ") VALUES(" + sqlInsertValues + "); SELECT SCOPE_IDENTITY() AS [lastInsertedVideoId]"; 

然后打电话

 int lastVideoInsertedId = Convert.ToInt32(sqlCmd.ExecuteScalar()); 

而不是.ExecuteNonQuery和“//获取最后插入的videoID”注释后面的代码块。

应从第一个命令( SELECTRETURNOUT )中提取SCOPE_IDENTITY()并将其传递给下一个命令。 这样,我的意思是SELECT_IDENTITY()应该在第一个命令的末尾。 在SQL 2008中,还有一些额外的语法可以将值作为INSERT一部分返回,这使得这更简单。

或者更有效:将命令组合成一个以避免往返。