开发者

Entity framework transaction error after deleting a row and inserting a new row with same primary key

I am using ASP.NET MVC2 in Visual Studio 2008. I believe the SQL Server is 2005. I am using Entity Framework to access the database.

I've got the following table with a composite primary key based upon iRequest and sCode:

RequestbyCount
    iRequest  integer
    sCode     varchar(10)
    iCount    integer

iRequest is a foreign key to a list of requests.

When a request is updated, I want to clear out the existing RequestbyCounts for that request and then add in the new RequestbyCounts. More than likely, the only difference between the old rows will be the Count.

For my code, I attempt it as follows:

//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);开发者_Go百科
}

//  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

The issue is when I run it with the intermediate SaveChanges line uncommented, it works as desired. But my understanding is that doing this breaks the transaction apart.

If I leave the intermediate SaveChanges commented out as above, the process fails and I receive a

Violation of PRIMARY KEY constraint 'PK_RequestbyCount'. Cannot insert duplicate key in object 'dbo.RequestbyCount'.\r\nThe statement has been terminated.

Obviously, without doing the intermediate SaveChanges, the old rows are NOT removed as desired.

I do NOT want the results saved unless everything succeeds.

I would rather not take the following approach:

//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**
   }
}

Am I stuck doing the above code that basically makes a bunch of little calls to the database to check if an item exists?

Or is there some method that tell the framework to attempt to delete the rows I want but rollback if there is a failure inserting the new rows?


You don't appear to be using transactions at all. You need to wrap all your code in

using (TransactionScope transaction = new TransactionScope())
{
    ...
    transaction.Complete();
}

Even better

using (TransactionScope transaction = new TransactionScope())
{
    try
    { 
       your code 
       transaction.Complete();
    }
    catch(Exception)
    {
       // handle error
    }
}

Using the try/catch block will ensure that the transaction is not committed if an exception occurs, which is what you stated you wanted.

Lot's more on entity framework transactions at Microsoft's web site. The explanations there are quite good.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜