LINQ to SQL ERROR使用事务:违反PK约束无法在对象中插入重复键''该语句已终止

时间:2017-11-11 14:38:51

标签: c# linq-to-sql transactions .net-framework-version

我在交易中使用LINQ to SQL时遇到了一个奇怪的问题。

重现此行为的步骤:

  1. 插入一些记录
  2. 修改现有记录
  3. 执行SubmitChanges(System.Data.Linq.ConflictMode.ContinueOnConflict)之前,修改外部应用程序的上述记录(例如sqlserver管理工作室)
  4. 现在SubmitChanges(System.Data.Linq.ConflictMode.ContinueOnConflict)引发冲突错误
  5. 解决冲突
  6. 做另一个SubmitChanges(System.Data.Linq.ConflictMode.FailOnFirstConflict)
  7. 这里有错误:违反PRIMARY KEY约束 PK_EmployeeTerritories 。无法在对象 dbo.EmployeeTerritories 中插入重复键。该语句已被终止。
  8. 以下是重现此行为的c#代码,此代码使用NORTHWIND数据库:

    static void Main(string[] args)
    {
        using (Northwnd db = new Northwnd())
        {
            //=======================================================================================
            // RESTORE PREVIOUS STATUS ==============================================================
            //=======================================================================================
            EmployeeTerritory exitEt = (from et in db.EmployeeTerritories where et.EmployeeID == 5 && et.TerritoryID == "85014" select et).FirstOrDefault();
            if (exitEt != null)
                db.EmployeeTerritories.DeleteOnSubmit(exitEt);
            var existingRegToReset = (from er in db.Regions where er.RegionID == 2 select er).First();
            existingRegToReset.RegionDescription = "Western";
            db.SubmitChanges(System.Data.Linq.ConflictMode.FailOnFirstConflict);
            //=======================================================================================
            // RESTORE PREVIOUS STATUS ==============================================================
            //=======================================================================================
    
            EmployeeTerritory newEt = new EmployeeTerritory();
            newEt.EmployeeID = 5;
            newEt.TerritoryID = "85014";
            db.EmployeeTerritories.InsertOnSubmit(newEt);
    
            Order newO = new Order();
            newO.CustomerID = "WHITC";
            newO.EmployeeID = 5;
            newO.OrderDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day); 
            newO.RequiredDate= new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day);
            newO.ShippedDate= new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day);
            newO.ShipVia = 1;
            newO.Freight = (Decimal)4.56;
            newO.ShipName = "White Clover Markets";
            newO.ShipAddress = "1029 - 12th Ave. S.";
            newO.ShipCity = "Seattle";
            newO.ShipRegion = "WA";
            newO.ShipPostalCode = "98124";
            newO.ShipCountry = "USA";
            db.Orders.InsertOnSubmit(newO);
    
            var existingReg = (from er in db.Regions where er.RegionID == 2 select er).First();
            existingReg.RegionDescription = "Western1";
    
            Console.WriteLine("Submit the following update on database using Management Studio:'Update dbo.Region Set RegionDescription='Western2' Where RegionID=2'");
            Console.ReadLine();
            ChangeSet cs;
            using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required, TimeSpan.FromSeconds(0)))
            {
                try
                {
                    try
                    {
                        cs = db.GetChangeSet();
                        db.SubmitChanges(System.Data.Linq.ConflictMode.ContinueOnConflict);
                    }
                    catch (ChangeConflictException e)
                    {
                        Console.WriteLine(e.Message);
                        // Automerge database values for members that client
                        // has not modified.
                        foreach (ObjectChangeConflict occ in db.ChangeConflicts)
                            occ.Resolve(RefreshMode.KeepChanges);
                        cs = db.GetChangeSet();
                    }
                    // Submit succeeds on second try.
                    db.SubmitChanges(ConflictMode.FailOnFirstConflict);
                }
                catch (Exception ex)
                {
                    throw;
                }
            }
            cs = db.GetChangeSet();
        }
    }
    

    我们需要交易才能完成当前数据库之外的其他操作。

    感谢您的帮助

    的Fabio

0 个答案:

没有答案