来园子已经两年了,每次都是看,这次咱也写一次。
说一下今天遇到的Linq问题:
每一次插入流水表时,都需要查找表中最大的流水号+1,并且将该流水号返回,但是在同一个SubmitChange之内插入多条时,流水号就一直是表中实际最大的,而不是我上一次插入的最大的。不描述了 贴代码:
这个是DataContext
public class DataContext : LinqDataContext { public DataContext() : base() { } /// <summary> /// 打开隐式Linq事务 /// 对于在BeginTransaction()之前已经SubmitChanges()的操作不在此事务之内。 /// 开启事务以后,必须要Commit()提交事务才会更改到数据库中。 /// </summary> public void BeginTransaction() { if (this.Connection.State == ConnectionState.Closed) { this.Connection.Open(); this.Transaction = this.Connection.BeginTransaction(); } } /// <summary> /// 提交隐式Linq事务 /// 对于在BeginTransaction()之前已经SubmitChanges()的操作不在此事务之内。 /// </summary> public void Commit() { if (this.Transaction != null) this.Transaction.Commit(); } }
两个公用方法:
/// <summary> /// 取得数据表中最大的Number值 /// </summary> /// <param name="da"></param> /// <returns></returns> static int GetMaxNumber(DataContext da) { return (from v in da.LinqTable orderby v.Number descending select v.Number).FirstOrDefault(); } static void Continue() { Console.WriteLine("请按任意键继续"); Console.ReadKey(); }
表结构:
/* * LinqTable表结构 * ID int 自增主键 * Number int NOT NULL */
第一种情况:修改提交前可以重新查询获得已经更新的内容,读取的是内存中的 未使用隐式事务
//假设数据表中只有一条数据 1 1 Console.WriteLine("修改提交前可以重新查询获得已经更新的内容 未使用隐式事务"); Continue(); using (var da = new DataContext()) { var single = (from v in da.LinqTable where v.ID.Equals(1) select v).Single(); Console.WriteLine("读取ID为1的Number值为:" + single.Number); //输出:读取ID为1的Number值为:1 Continue(); single.Number = -single.Number; Console.WriteLine("将Number值修改为该值的相反数。"); Continue(); var newSingle = (from v in da.LinqTable where v.ID.Equals(1) select v).Single(); Console.WriteLine("未提交之前重新查询ID为1的Number值为:" + newSingle.Number); //输出:未提交之前重新查询ID为1的Number值为::-1 Continue(); da.SubmitChanges(); var submitSingle = (from v in da.LinqTable where v.ID.Equals(1) select v).Single(); Console.WriteLine("提交之后重新查询ID为1的Number值为:" + submitSingle.Number); //输出:提交之后重新查询ID为1的Number值为:-1 Continue(); } /* * 修改时,在未提交之前重新查询改对象的值是查询内存中的 * 但是新增时又不一样,请看下面 */
第二种情况:添加后未提交前取得的最大的Number值永远是数据表中真实的值,不是内存中的 未使用隐式事务
//假设数据表中只有一条数据 1 1 using (var da = new DataContext()) { LinqTable t1 = new LinqTable() { Number = GetMaxNumber(da) + 1, }; da.LinqTable.InsertOnSubmit(t1); Console.WriteLine("添加t1,t1的Number为:" + t1.Number + ",此时重新查询最大的Number为:" + GetMaxNumber(da)); //输出:添加t1,t1的Number为:2,此时重新查询最大的Number为:1 //想要的效果:添加t1,t1的Number为:2,此时重新查询最大的Number为:2 Continue(); LinqTable t2 = new LinqTable() { Number = GetMaxNumber(da) + 1, }; da.LinqTable.InsertOnSubmit(t2); Console.WriteLine("添加t2,t2的Number为:" + t2.Number + ",此时重新查询最大的Number为:" + GetMaxNumber(da)); //输出:添加t2,t2的Number为:2,此时重新查询最大的Number为:1 //想要的效果:添加t2,t2的Number为:3,此时重新查询最大的Number为:3 Continue(); da.SubmitChanges(); } /* * 根据第一种情况,结果应该是我想要的那种结果,但事实上不是。 * 这个是什么原因呢?求解。 */
第三种情况:开启隐式事务,添加后提交前取得的最大的Number值是我想要的值,最后再Commit
//假设数据表中只有一条数据 1 1 using (var da = new DataContext()) { da.BeginTransaction();//开启隐式事务 LinqTable t1 = new LinqTable() { Number = GetMaxNumber(da) + 1, }; da.LinqTable.InsertOnSubmit(t1); da.SubmitChanges();//插入后立即提交 Console.WriteLine("添加t1,t1的Number为:" + t1.Number + ",此时重新查询最大的Number为:" + GetMaxNumber(da)); //输出:添加t1,t1的Number为:2,此时重新查询最大的Number为:2 //是我想要的效果 Continue(); LinqTable t2 = new LinqTable() { Number = GetMaxNumber(da) + 1, }; da.LinqTable.InsertOnSubmit(t2); da.SubmitChanges();//插入后立即提交 Console.WriteLine("添加t2,t2的Number为:" + t2.Number + ",此时重新查询最大的Number为:" + GetMaxNumber(da)); //输出:添加t2,t2的Number为:3,此时重新查询最大的Number为:3 //是我想要的效果 Continue(); da.Commit(); } /* * 这次开启了隐式事务,达到了我想要的结果,但是第二种情况为什么不行? * TransactionCope 需要开启DTC 不建议使用 */
这就是今天遇到的问题,现在没办法只能开启隐式事务了,不过为什么第二种情况达不到我想要的结果呢?求大神解。