问题描述
我无法理解的是是否可以对上下文进行更改并在提交之前在同一个事务中获取更改.
What I can't understand is if its possible to make changes to the context and get the changes in the same transaction before its commited.
这就是我要找的:
using (var scope = new TransactionScope(TransactionScopeOption.Required))
{
using (var context = new DbContext())
{
//first I want to update an item in the context, not to the db
Item thisItem = context.Items.First();
thisItem.Name = "Update name";
context.SaveChanges(); //Save change to this context
//then I want to do a query on the updated item on the current context, not against the db
Item thisUpdatedItem = context.Items.Where(a=>a.Name == "Update name").First();
//do some more query
}
//First here I want it to commit all the changes in the current context to the db
scope.Complete();
}
有人可以帮我理解并展示一个工作模式吗?
Can someone help me understand and show me a working pattern?
推荐答案
是的,这是可以做到的,当你想将实体插入数据库并使用自动- 为下一次插入或更新生成 id
Yes, it's possible to do and it's very useful when you want to insert a entity to database and use the auto-generated id for the next insert or update
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();
}
}
因为您的问题还询问了工作模式,所以这是我的工作代码(使用 FluentApi、DbContext 和事务).我和你有同样的问题:).希望对你有帮助
Because your question also asked about a working pattern, here's my working code (with use of FluentApi, DbContext & Transaction). I was having the same issue as you :). Hope it helps you
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();
}
}
示例用法:
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();
这篇关于将 TransactionScope 与实体框架 6 一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!