Eu tenho um problema com o Entity Framework no Asp.net. Quero obter o valor do ID sempre que adiciono um objeto ao banco de dados. Como posso fazer isso?
SaveChanges
imediatamente apenas para obter o ID. Leia mais aqui .
Eu tenho um problema com o Entity Framework no Asp.net. Quero obter o valor do ID sempre que adiciono um objeto ao banco de dados. Como posso fazer isso?
SaveChanges
imediatamente apenas para obter o ID. Leia mais aqui .
Respostas:
É bem fácil Se você estiver usando DB gerado Ids (como IDENTITY
em MS SQL), você só precisa adicionar entidade ObjectSet
e SaveChanges
na relacionado ObjectContext
. Id
será preenchido automaticamente para você:
using (var context = new MyContext())
{
context.MyEntities.Add(myNewObject);
context.SaveChanges();
int id = myNewObject.Id; // Yes it's here
}
A estrutura da entidade, por padrão, segue cada INSERT
uma delas SELECT SCOPE_IDENTITY()
quando Id
s gerados automaticamente são usados.
Eu estava usando a resposta de Ladislav Mrnka para recuperar IDs com sucesso ao usar o Entity Framework, no entanto, estou postando aqui porque estava com falta de usá-lo (ou seja, onde não era necessário) e pensei em publicar minhas descobertas aqui em caso as pessoas estejam procurando "resolver" o problema que tive.
Considere um objeto Pedido que tenha um relacionamento de chave estrangeira com o Cliente. Quando adicionei um novo cliente e um novo pedido ao mesmo tempo, estava fazendo algo parecido com isto;
var customer = new Customer(); //no Id yet;
var order = new Order(); //requires Customer.Id to link it to customer;
context.Customers.Add(customer);
context.SaveChanges();//this generates the Id for customer
order.CustomerId = customer.Id;//finally I can set the Id
No entanto, no meu caso, isso não foi necessário porque eu tinha um relacionamento de chave estrangeira entre customer.Id e order.CustomerId
Tudo que eu tinha que fazer era isso;
var customer = new Customer(); //no Id yet;
var order = new Order{Customer = customer};
context.SaveChanges();//adds customer.Id to customer and the correct CustomerId to order
Agora, quando eu salvo as alterações, o ID gerado para o cliente também é adicionado ao pedido. Não preciso das etapas adicionais
Estou ciente de que isso não responde à pergunta original, mas achei que poderia ajudar os desenvolvedores novatos na EF a usarem excessivamente a resposta mais votada para algo que pode não ser necessário.
Isso também significa que as atualizações são concluídas em uma única transação, evitando potencialmente os dados do orphin (todas as atualizações são concluídas ou nenhuma).
Você precisa recarregar a entidade após salvar as alterações. Porque foi alterado por um gatilho de banco de dados que não pode ser rastreado pelo EF. Portanto, precisamos recarregar a entidade novamente do banco de dados,
db.Entry(MyNewObject).GetDatabaseValues();
Então
int id = myNewObject.Id;
Veja a resposta @jayantha na pergunta abaixo:
Como posso obter o ID da entidade inserida na estrutura da entidade ao usar o defaultValue?
Procurar a resposta @christian na pergunta abaixo também pode ajudar:
.GetDatabaseValues();
se você acabou de salvar seu modelo no banco de dados. O ID deve preencher novamente o modelo automaticamente.
GetDatabaseValues()
se não souber o ID do objeto a ser procurado no banco de dados?
Por favor, consulte este link.
http://www.ladislavmrnka.com/2011/03/the-bug-in-storegeneratedpattern-fixed-in-vs-2010-sp1/
Você deve definir a propriedade StoreGeneratedPattern como identidade e, em seguida, tentar seu próprio código.
Ou então você também pode usar isso.
using (var context = new MyContext())
{
context.MyEntities.AddObject(myNewObject);
context.SaveChanges();
int id = myNewObject.Id; // Your Identity column ID
}
StoreGeneratedPattern
foi a peça que faltava para mim.
O objeto que você está salvando deve ter um correto Id
após a propagação das alterações no banco de dados.
Você pode obter o ID apenas após salvar, em vez disso, pode criar um novo Guid e atribuir antes de salvar.
Me deparei com uma situação em que preciso inserir os dados no banco de dados e, simultaneamente, exigir o ID primário usando a estrutura da entidade. Solução:
long id;
IGenericQueryRepository<myentityclass, Entityname> InfoBase = null;
try
{
InfoBase = new GenericQueryRepository<myentityclass, Entityname>();
InfoBase.Add(generalinfo);
InfoBase.Context.SaveChanges();
id = entityclassobj.ID;
return id;
}
Todas as respostas são muito adequadas para seus próprios cenários, o que fiz de diferente é que atribuai o PK int diretamente do objeto (TEntity) que Add () retornou a uma variável int como esta;
using (Entities entities = new Entities())
{
int employeeId = entities.Employee.Add(new Employee
{
EmployeeName = employeeComplexModel.EmployeeName,
EmployeeCreatedDate = DateTime.Now,
EmployeeUpdatedDate = DateTime.Now,
EmployeeStatus = true
}).EmployeeId;
//...use id for other work
}
então, em vez de criar um novo objeto inteiro, basta pegar o que deseja :)
EDIT Para Mr. @GertArnold:
Add
(se for esse o caso DbSet.Add
) não atribui um valor magicamente EmployeeId
.
SaveChanges
. Impossível. A menos que você tenha algum outro processo que atribua EmployeeId
, por exemplo, no Employee
construtor. OU você está no núcleo da EF usando ForSqlServerUseSequenceHiLo
. Enfim, você não está dando a imagem toda.
Repository.addorupdate(entity, entity.id);
Repository.savechanges();
Var id = entity.id;
Isso vai funcionar.
Repository
é. E "isso vai funcionar" é uma explicação!
Existem duas estratégias:
Use o banco de dados gerado ID
( int
ouGUID
)
Contras:
Você deve executar SaveChanges()
para obter oID
apenas as entidades salvas.
Prós:
Pode usar int
identidade.
Usar cliente gerado ID
- apenas GUID.
Prós: Minificação de SaveChanges
operações. Capaz de inserir um grande gráfico de novos objetos por uma operação.
Contras:
Permitido apenas para GUID
Quando você usa o código EF 6.x primeiro
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
e inicializar uma tabela de banco de dados, ele colocará um
(newsequentialid())
dentro das propriedades da tabela, sob o cabeçalho Valor padrão ou Ligação, permitindo que o ID seja preenchido à medida que é inserido.
O problema é se você criar uma tabela e adicionar o
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
parte depois, futuros bancos de dados de atualização não adicionarão novamente o (newsequentialid ())
Corrigir a maneira correta é limpar a migração, excluir o banco de dados e migrar novamente ... ou você pode simplesmente adicionar (newsequentialid ()) ao designer da tabela.
when -column- is NULL, then NEWID()