Deseja usar a identidade retornada da inserção na inserção subsequente em uma transação
Pergunta
Estou usando o Massive de Rob Conery para acesso ao banco de dados.Quero envolver uma transação em torno de algumas inserções, mas a segunda inserção usa a identidade retornada da primeira inserção.Não é óbvio para mim como fazer isso em uma transação.Agradecemos alguma ajuda.
var commandList = new List<DbCommand>
{
contactTbl.CreateInsertCommand(new
{
newContact.Name,
newContact.Contact,
newContact.Phone,
newContact.ForceChargeThreshold,
newContact.MeterReadingMethodId,
LastModifiedBy = userId,
LastModifiedDate = modifiedDate,
}),
branchContactTbl.CreateInsertCommand(new
{
newContact.BranchId,
ContactId = ????, <-- how to set Id as identity from previous command
}),
};
Solução
Você pode simplesmente fazer isso em um procedimento armazenado?Você pode usar o scope_identity ou melhor ainda a cláusula de saída para obter o (s) valor (es) que você precisa.E todas as inserções em todas as tabelas estão em uma transação que pode ser revertida se alguma delas falhar.
Outras dicas
Faça uma consulta entre essas duas inserções, este método do Massive pode ser útil:
public object Scalar(string sql, params object[] args) {
object result = null;
using (var conn = OpenConnection()) {
result = CreateCommand(sql, conn, args).ExecuteScalar();
}
return result;
}
Seu sql será="select scope_identity ()"
ATUALIZAÇÃO 26/02/2013
Olhando novamente para o código do Massive, não há maneira confiável de recuperar o último ID inserido.
O código acima funcionará apenas quando a conexão que faz "select scope_identity ()" for agrupada.(Deve ser a mesma conexão que fez a inserção).
O método table.Insert(..)
massivo retorna Dynamic que contém o campo ID, que é preenchido com "SELECT @@ IDENTITY".Ele obtém a última ID inserida do escopo global, que é um bug óbvio (aparente em cenários de multithreading).