首页 新闻 会员 周边 捐助

DbContext 如何实现保存后不提交数据库?

0
悬赏园豆:5 [已解决问题] 解决于 2015-01-13 16:12

如题,DbContext在SaveChanges()之后会将结果提交到数据库。

但因为项目过程中业务的特殊性(先不考虑场景的合理性,咱们只看这个问题),需要在一个上下文中多次SaveChanges,但直到最后再提交数据库。

怎样设置SaveChanges的时候不提交数据库呢?

在以往ObjectContext中可以使用 
context.Connection.Open();
System.Data.Common.DbTransaction tran = context.Connection.BeginTransaction();

最后tran.Commit();或tran.Rollback();来实现,但在DbContext中使用相同方式则抛出异常
"如果分配给命令的连接位于本地挂起事务中,ExecuteReader 要求命令拥有事务。命令的 Transaction 属性尚未初始化。" 

简而言之,如何使用DbContext实现,一个事务中update多次,最后一次性commit或Rollback。请各路达人指教。

Greatcqi的主页 Greatcqi | 初学一级 | 园豆:175
提问于:2015-01-09 11:56
< >
分享
最佳答案
0

http://blog.csdn.net/yanwushu/article/details/10307801

试试这个,用事务。

如果分配给命令的连接位于本地挂起事务中,ExecuteReader 要求命令拥有事务。命令的 Transaction 属性尚未初始化。

你出现这个错误,肯定是没有实例化这个对象。或者实例化错了这个对象。

首先添加引用程序集System.Transactions

然后在你要实例化的地方引用这个!

收获园豆:5
大楚打码人 | 老鸟四级 |园豆:4313 | 2015-01-09 12:02

谢谢,TransactionScope知道的,但用了以后就变成分布式事物的方式了,虽然实际上不会启动分布式事务,但还是想用其他方式

Greatcqi | 园豆:175 (初学一级) | 2015-01-09 16:45
其他回答(6)
0

DbContext dcCtx = new DbContext;

// 随便修改,修改多少次都行。

dbCtx.SaveChanges(); // 只保存一次

Launcher | 园豆:45050 (高人七级) | 2015-01-09 11:59

 我想请教大家的是

using(DbContext ctx = new DbContext())

{

  do something;

  ctx.saveChanges();//保存结果,但未提交数据库

  do another things;

  ctx.saveChanges();//保存结果,但未提交数据库

  //提交数据库

}

该怎么做?

支持(0) 反对(0) Greatcqi | 园豆:175 (初学一级) | 2015-01-10 23:28

简而言之,如何使用DbContext实现,一个事务中update多次,最后一次性commit或Rollback

支持(0) 反对(0) Greatcqi | 园豆:175 (初学一级) | 2015-01-10 23:30

@Greatcqi: 我先问你一个问题,你想要的结果是不是这样:

using(DbContext ctx = new DbContext())

{

    A a = new A(){Id = 1};

     ctx.DbSet<A>.Add(a);  // 保存结果了,在当前上下文中,但未提交数据库

}

 

using(DbContext ctx = new DbContext())

{

    Assert(ctx.DbSet<A>.Contans(o->o.Id == 1));  // 在其它上下文中保存的结果,虽然没提交到数据库,但是在这里也应该能查询到。
}

支持(0) 反对(0) Launcher | 园豆:45050 (高人七级) | 2015-01-11 09:26
0

问题只有一个.你让EF怎么判定你的"直到最后"是什么时候

吴瑞祥 | 园豆:29449 (高人七级) | 2015-01-09 12:01

范围在

using(DbContext ctx = new DbContext())

之内

支持(0) 反对(0) Greatcqi | 园豆:175 (初学一级) | 2015-01-09 16:08

@Greatcqi: 如果一个默认不提交就是回滚事务.

这种情况你怎么办

支持(0) 反对(0) 吴瑞祥 | 园豆:29449 (高人七级) | 2015-01-09 17:54

@吴瑞祥: 不知道您看清问题没有

在以往ObjectContext中可以使用 
context.Connection.Open();
System.Data.Common.DbTransaction tran = context.Connection.BeginTransaction();

最后tran.Commit();或tran.Rollback();

在ObjectContext中,这样可以实现最后统一回滚或提交

支持(0) 反对(0) Greatcqi | 园豆:175 (初学一级) | 2015-01-10 17:10
0

重写SaveChanges,代码就是Do nothing。

爱编程的大叔 | 园豆:30844 (高人七级) | 2015-01-09 12:07
0

我只能说你的逻辑除了点问题,导致你需要通过解决SaveChanges()的问题,还是好好解决逻辑问题吧

刘宏玺 | 园豆:14020 (专家六级) | 2015-01-09 13:42

问题里就说了,不考虑业务逻辑如何。纯粹的向大家请教技术问题。你这样的回答毫无意义

支持(0) 反对(0) Greatcqi | 园豆:175 (初学一级) | 2015-01-09 16:10
0
           var objectContext = ((IObjectContextAdapter) _dataContext).ObjectContext;
            if (objectContext .Connection.State != ConnectionState.Open)
            {
               objectContext .Connection.Open();
            }
var transaction = objectContext .Connection.BeginTransaction();

楼主,这样写试试

zhengldg | 园豆:462 (菜鸟二级) | 2015-01-09 14:31

ObjectContext没有问题。我的问题是上下文范围是

using(DbContext ctx = new DbContext())

支持(0) 反对(0) Greatcqi | 园豆:175 (初学一级) | 2015-01-09 16:09
0

实际上已经超出上下文范围了,每次using 都是不同的对象 怎么来最后 savechanges?

老老实实用事务包裹吧,要么就全局dbcontext

Y2zz | 园豆:393 (菜鸟二级) | 2015-01-13 01:14

我想请教大家的是

using(DbContext ctx = new DbContext())

{

  do something;

  ctx.saveChanges();//保存结果,但未提交数据库

  do another things;

  ctx.saveChanges();//保存结果,但未提交数据库

  //提交数据库

}

该怎么做?

支持(0) 反对(0) Greatcqi | 园豆:175 (初学一级) | 2015-01-13 10:35

@Greatcqi: 既要写savechanges,然后又不让人家去提交数据库。。。 在最后savechanges就行了啦。。。

其实在insert外键表的时候 是必须先提交后才能写关联数据的,所以没法在最后savechanges

另外:你这个保存结果是个什么意思?保存在内存中? 试试 db.Entry(xx entity).State = EntityState.Modified,将实体标记为已修改 savechanges时才执行

支持(0) 反对(0) Y2zz | 园豆:393 (菜鸟二级) | 2015-01-13 10:43
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册