删除一行并插入具有相同主键的新行后,实体框架事务出错

问题描述

| 我在Visual Studio 2008中使用ASP.NET MVC2。我相信SQL Server是2005。我正在使用实体框架访问数据库。 下表具有基于
iRequest
sCode
的复合主键:
RequestbyCount
    iRequest  integer
    sCode     varchar(10)
    iCount    integer
“ 0”是请求列表的外键。 更新请求后,我想为该请求清除现有的
RequestbyCounts
,然后添加新的
RequestbyCounts
。老行之间唯一的区别是计数。 对于我的代码,我尝试如下进行操作:
//delete ALL our old requests
var oldEquipList = (from eq in myDB.dbEquipmentRequestedbyCountSet
                    where eq.iRequestID == oldData.iRequestID
                    select eq).ToList();
foreach (var oldEquip in oldEquipList)
{
     myDB.DeleteObject(oldEquip);
}

//  myDB.SaveChanges();    <---- adding this line makes it work

//add in our new requests
foreach (var equip in newData.RequestList)   //newData.RequestList is a List object
{
   if (equip.iCount > 0)
   {
    //add in our actual request items
      RequestbyCount reqEquip = new RequestbyCount();
      reqEquip.sCodePrefix = equip.sCodePrefix;
      reqEquip.UserRequest = newRequest;
      reqEquip.iCount = equip.iCount;
      myDB.AddToRequestbyCount(reqEquip);
   }
}

myDB.SaveChanges();   //save our results
问题是,当我在不加注释的中间
SaveChanges
行的情况下运行它时,它可以按需运行。但是我的理解是,这样做可以使交易分开。 如果我将中间的SaveChanges保留为上述注释,则该过程失败,并且我收到   违反PRIMARY KEY约束   \'PK_RequestbyCount \'。无法插入   对象中的重复键   \'dbo.RequestbyCount \'。\\ r \\ n语句   已终止。 显然,如果不执行中间的
SaveChanges
,则不会按需删除旧行。 除非一切成功,否则我不希望保存结果。 我宁愿不采用以下方法:
//add in our new requests
foreach (var equip in newData.RequestList)
{
   if (equip.iCount > 0) && (**it isn\'t in the database**)
   {
    //add in our actual request items
      RequestbyCount reqEquip = new RequestbyCount();
      reqEquip.sCodePrefix = equip.sCodePrefix;
      reqEquip.UserRequest = newRequest;
      reqEquip.iCount = equip.iCount;
      myDB.AddToRequestbyCount(reqEquip);
   } else if (**it is in the database**) && (equip.iCount == 0) {
      **remove from database**
   } else {
      **edit the value in the database**
   }
}
我是否坚持执行上面的代码,该代码基本上对数据库进行了一些小调用以检查某项是否存在? 还是有某种方法告诉框架尝试删除我想要的行,但是如果插入新行失败,则回滚?     

解决方法

您似乎根本没有使用事务。您需要包装所有代码
using (TransactionScope transaction = new TransactionScope())
{
    ...
    transaction.Complete();
}
更好
using (TransactionScope transaction = new TransactionScope())
{
    try
    { 
       your code 
       transaction.Complete();
    }
    catch(Exception)
    {
       // handle error
    }
}
使用try / catch块将确保如果发生异常(即您想要的异常),则不会提交事务。 有关Microsoft实体网站上的实体框架交易的更多信息。那里的解释很好。     

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...