Tak, jest to możliwe do zrobienia i to bardzo przydatne, gdy chcesz wstawić podmiot do bazy i używać automatycznie wygenerowane identyfikator dla następnej wkładki lub zaktualizować
using (var context = new DbContext())
{
using (var transaction = context.Database.BeginTransaction()) {
var item = new Item();
context.Items.Insert(item);
context.SaveChanges(); // temporary insert to db to get back the auto-generated id
// do some other things
var otherItem = context.OtherItems.First();
// use the inserted id
otherItem.Message = $"You just insert item with id = {item.Id} to database";
transaction.Commit();
}
}
Ze względu na swoje pytanie zapytano także o działający wzorzec, oto mój działający kod (przy użyciu FluentApi, DbContext & Transakcja). Miałem ten sam problem co ty :). Nadzieję, że to pomaga
public class FluentUnitOfWork : IDisposable
{
private DbContext Context { get; }
private DbContextTransaction Transaction { get; set; }
public FluentUnitOfWork(DbContext context)
{
Context = context;
}
public FluentUnitOfWork BeginTransaction()
{
Transaction = Context.Database.BeginTransaction();
return this;
}
public FluentUnitOfWork DoInsert<TEntity>(TEntity entity) where TEntity : class
{
Context.Set<TEntity>().Add(entity);
return this;
}
public FluentUnitOfWork DoInsert<TEntity>(TEntity entity, out TEntity inserted) where TEntity : class
{
inserted = Context.Set<TEntity>().Add(entity);
return this;
}
public FluentUnitOfWork DoUpdate<TEntity>(TEntity entity) where TEntity : class
{
Context.Entry(entity).State = EntityState.Modified;
return this;
}
public FluentUnitOfWork SaveAndContinue()
{
try
{
Context.SaveChanges();
}
catch (DbEntityValidationException dbEx)
{
// add your exception handling code here
}
return this;
}
public bool EndTransaction()
{
try
{
Context.SaveChanges();
Transaction.Commit();
}
catch (DbEntityValidationException dbEx)
{
// add your exception handling code here
}
return true;
}
public void RollBack()
{
Transaction.Rollback();
Dispose();
}
public void Dispose()
{
Transaction?.Dispose();
Context?.Dispose();
}
}
użycie Sample:
var status = BeginTransaction()
// First Part
.DoInsert(entity1)
.DoInsert(entity2)
.DoInsert(entity3)
.DoInsert(entity4)
.SaveAndContinue()
// Second Part
.DoInsert(statusMessage.SetPropertyValue(message => message.Message, $"Just got new message {entity1.Name}"))
.EndTransaction();
Czy to wstawi wiersz do bazy danych, a następnie, jeśli transakcja zostanie wycofana, czy usunie wiersz? Lub jak otrzymasz identyfikator rzędu? @ kienct89 –
to nie wstawi wiersza w db, dopóki nie wywołasz transaction.care(), identyfikator zostanie tymczasowo przypisany do pamięci –
ok, dziękuję za przykład i opis. Testuję to i wracam do ciebie –