• 的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

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

     
  • 相关阅读:
    vbScript首字拼音查询
    C#读取U盘序列号
    下拉 回车 筛选
    Oracle的汉字转拼音首字母的函数
    sql 触发器禁止和启用
    List.FindAll 方法
    MyControl 常用操作
    List.Find 方法
    regsvr32 C:\WINDOWS\system32\cell32.ocx
    2222222
  • 原文地址:https://www.cnblogs.com/goyuanfang/p/3272755.html
Copyright © 2020-2023  润新知