的Linq未提交之前插入/修改时重新查询不准确问题

来园子已经两年了,每次都是看,这次咱也写一次。

说一下今天遇到的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();
        }
    }
View Code

 两个公用方法:

/// <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();
        }
View Code

表结构:

 /*
             * LinqTable表结构
             * ID int 自增主键
             * Number int NOT NULL
             */
View Code

第一种情况:修改提交前可以重新查询获得已经更新的内容,读取的是内存中的 未使用隐式事务

 //假设数据表中只有一条数据 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();
            }

            /*
             * 修改时,在未提交之前重新查询改对象的值是查询内存中的
             * 但是新增时又不一样,请看下面
             */
View Code
第二种情况:添加后未提交前取得的最大的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();
            }

            /*
             * 根据第一种情况,结果应该是我想要的那种结果,但事实上不是。
             * 这个是什么原因呢?求解。
             */
View Code

第三种情况:开启隐式事务,添加后提交前取得的最大的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 不建议使用
             */
View Code

这就是今天遇到的问题,现在没办法只能开启隐式事务了,不过为什么第二种情况达不到我想要的结果呢?求大神解。

 

 

posted @ 2013-08-21 15:23  GoYF  阅读(1100)  评论(5编辑  收藏  举报