的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

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

 

 

你可能感兴趣的:(LINQ)